refactor: message & notification
							parent
							
								
									d211688059
								
							
						
					
					
						commit
						73ce708868
					
				|  | @ -8,6 +8,7 @@ import InfoCircleFilled from '@ant-design/icons-vue/InfoCircleFilled'; | |||
| import type { Key, VueNode } from '../_util/type'; | ||||
| import type { NotificationInstance } from '../vc-notification/Notification'; | ||||
| import classNames from '../_util/classNames'; | ||||
| import useStyle from './style'; | ||||
| 
 | ||||
| let defaultDuration = 3; | ||||
| let defaultTop: string; | ||||
|  | @ -80,6 +81,7 @@ function getMessageInstance(args: MessageArgsProps, callback: (i: NotificationIn | |||
|       getContainer: getContainer || args.getPopupContainer, | ||||
|       maxCount, | ||||
|       name: 'message', | ||||
|       useStyle, | ||||
|     }, | ||||
|     (instance: any) => { | ||||
|       if (messageInstance) { | ||||
|  |  | |||
|  | @ -1,74 +0,0 @@ | |||
| @import '../../style/themes/index'; | ||||
| @import '../../style/mixins/index'; | ||||
| 
 | ||||
| @message-prefix-cls: ~'@{ant-prefix}-message'; | ||||
| 
 | ||||
| .@{message-prefix-cls} { | ||||
|   .reset-component(); | ||||
| 
 | ||||
|   position: fixed; | ||||
|   top: 8px; | ||||
|   left: 0; | ||||
|   z-index: @zindex-message; | ||||
|   width: 100%; | ||||
|   pointer-events: none; | ||||
| 
 | ||||
|   &-notice { | ||||
|     padding: 8px; | ||||
|     text-align: center; | ||||
|   } | ||||
| 
 | ||||
|   &-notice-content { | ||||
|     display: inline-block; | ||||
|     padding: @message-notice-content-padding; | ||||
|     background: @message-notice-content-bg; | ||||
|     border-radius: @border-radius-base; | ||||
|     box-shadow: @shadow-2; | ||||
|     pointer-events: all; | ||||
|   } | ||||
| 
 | ||||
|   &-success .@{iconfont-css-prefix} { | ||||
|     color: @success-color; | ||||
|   } | ||||
| 
 | ||||
|   &-error .@{iconfont-css-prefix} { | ||||
|     color: @error-color; | ||||
|   } | ||||
| 
 | ||||
|   &-warning .@{iconfont-css-prefix} { | ||||
|     color: @warning-color; | ||||
|   } | ||||
| 
 | ||||
|   &-info .@{iconfont-css-prefix}, | ||||
|   &-loading .@{iconfont-css-prefix} { | ||||
|     color: @info-color; | ||||
|   } | ||||
| 
 | ||||
|   .@{iconfont-css-prefix} { | ||||
|     position: relative; | ||||
|     top: 1px; | ||||
|     margin-right: 8px; | ||||
|     font-size: @font-size-lg; | ||||
|   } | ||||
| 
 | ||||
|   &-notice.@{ant-prefix}-move-up-leave.@{ant-prefix}-move-up-leave-active { | ||||
|     animation-name: MessageMoveOut; | ||||
|     animation-duration: 0.3s; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @keyframes MessageMoveOut { | ||||
|   0% { | ||||
|     max-height: 150px; | ||||
|     padding: 8px; | ||||
|     opacity: 1; | ||||
|   } | ||||
| 
 | ||||
|   100% { | ||||
|     max-height: 0; | ||||
|     padding: 0; | ||||
|     opacity: 0; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @import './rtl'; | ||||
|  | @ -0,0 +1,178 @@ | |||
| // deps-lint-skip-all
 | ||||
| import { Keyframes } from '../../_util/cssinjs'; | ||||
| import type { FullToken, GenerateStyle } from '../../theme/internal'; | ||||
| import { genComponentStyleHook, mergeToken } from '../../theme/internal'; | ||||
| import { resetComponent } from '../../_style'; | ||||
| 
 | ||||
| /** Component only token. Which will handle additional calculation of alias token */ | ||||
| export interface ComponentToken { | ||||
|   // Component token here
 | ||||
|   height: number; | ||||
|   zIndexPopup: number; | ||||
| } | ||||
| 
 | ||||
| interface MessageToken extends FullToken<'Message'> { | ||||
|   // Custom token here
 | ||||
|   messageNoticeContentPadding: string; | ||||
| } | ||||
| 
 | ||||
| const genMessageStyle: GenerateStyle<MessageToken> = token => { | ||||
|   const { | ||||
|     componentCls, | ||||
|     iconCls, | ||||
|     boxShadowSecondary, | ||||
|     colorBgElevated, | ||||
|     colorSuccess, | ||||
|     colorError, | ||||
|     colorWarning, | ||||
|     colorInfo, | ||||
|     fontSizeLG, | ||||
|     motionEaseInOutCirc, | ||||
|     motionDurationSlow, | ||||
|     marginXS, | ||||
|     paddingXS, | ||||
|     borderRadiusLG, | ||||
|     zIndexPopup, | ||||
|     // Custom token
 | ||||
|     messageNoticeContentPadding, | ||||
|   } = token; | ||||
| 
 | ||||
|   const messageMoveIn = new Keyframes('MessageMoveIn', { | ||||
|     '0%': { | ||||
|       padding: 0, | ||||
|       transform: 'translateY(-100%)', | ||||
|       opacity: 0, | ||||
|     }, | ||||
| 
 | ||||
|     '100%': { | ||||
|       padding: paddingXS, | ||||
|       transform: 'translateY(0)', | ||||
|       opacity: 1, | ||||
|     }, | ||||
|   }); | ||||
| 
 | ||||
|   const messageMoveOut = new Keyframes('MessageMoveOut', { | ||||
|     '0%': { | ||||
|       maxHeight: token.height, | ||||
|       padding: paddingXS, | ||||
|       opacity: 1, | ||||
|     }, | ||||
|     '100%': { | ||||
|       maxHeight: 0, | ||||
|       padding: 0, | ||||
|       opacity: 0, | ||||
|     }, | ||||
|   }); | ||||
| 
 | ||||
|   return [ | ||||
|     // ============================ Holder ============================
 | ||||
|     { | ||||
|       [componentCls]: { | ||||
|         ...resetComponent(token), | ||||
|         position: 'fixed', | ||||
|         top: marginXS, | ||||
|         width: '100%', | ||||
|         pointerEvents: 'none', | ||||
|         zIndex: zIndexPopup, | ||||
| 
 | ||||
|         [`${componentCls}-move-up`]: { | ||||
|           animationFillMode: 'forwards', | ||||
|         }, | ||||
|         [` | ||||
|         ${componentCls}-move-up-appear, | ||||
|         ${componentCls}-move-up-enter | ||||
|       `]: {
 | ||||
|           animationName: messageMoveIn, | ||||
|           animationDuration: motionDurationSlow, | ||||
|           animationPlayState: 'paused', | ||||
|           animationTimingFunction: motionEaseInOutCirc, | ||||
|         }, | ||||
|         [` | ||||
|         ${componentCls}-move-up-appear${componentCls}-move-up-appear-active, | ||||
|         ${componentCls}-move-up-enter${componentCls}-move-up-enter-active | ||||
|       `]: {
 | ||||
|           animationPlayState: 'running', | ||||
|         }, | ||||
|         [`${componentCls}-move-up-leave`]: { | ||||
|           animationName: messageMoveOut, | ||||
|           animationDuration: motionDurationSlow, | ||||
|           animationPlayState: 'paused', | ||||
|           animationTimingFunction: motionEaseInOutCirc, | ||||
|         }, | ||||
|         [`${componentCls}-move-up-leave${componentCls}-move-up-leave-active`]: { | ||||
|           animationPlayState: 'running', | ||||
|         }, | ||||
|         '&-rtl': { | ||||
|           direction: 'rtl', | ||||
|           span: { | ||||
|             direction: 'rtl', | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
| 
 | ||||
|     // ============================ Notice ============================
 | ||||
|     { | ||||
|       [`${componentCls}-notice`]: { | ||||
|         padding: paddingXS, | ||||
|         textAlign: 'center', | ||||
| 
 | ||||
|         [iconCls]: { | ||||
|           verticalAlign: 'text-bottom', | ||||
|           marginInlineEnd: marginXS, // affected by ltr or rtl
 | ||||
|           fontSize: fontSizeLG, | ||||
|         }, | ||||
| 
 | ||||
|         [`${componentCls}-notice-content`]: { | ||||
|           display: 'inline-block', | ||||
|           padding: messageNoticeContentPadding, | ||||
|           background: colorBgElevated, | ||||
|           borderRadius: borderRadiusLG, | ||||
|           boxShadow: boxShadowSecondary, | ||||
|           pointerEvents: 'all', | ||||
|         }, | ||||
| 
 | ||||
|         [`${componentCls}-success ${iconCls}`]: { | ||||
|           color: colorSuccess, | ||||
|         }, | ||||
|         [`${componentCls}-error ${iconCls}`]: { | ||||
|           color: colorError, | ||||
|         }, | ||||
|         [`${componentCls}-warning ${iconCls}`]: { | ||||
|           color: colorWarning, | ||||
|         }, | ||||
|         [` | ||||
|         ${componentCls}-info ${iconCls}, | ||||
|         ${componentCls}-loading ${iconCls}`]: {
 | ||||
|           color: colorInfo, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
| 
 | ||||
|     // ============================= Pure =============================
 | ||||
|     { | ||||
|       [`${componentCls}-notice-pure-panel`]: { | ||||
|         padding: 0, | ||||
|         textAlign: 'start', | ||||
|       }, | ||||
|     }, | ||||
|   ]; | ||||
| }; | ||||
| 
 | ||||
| // ============================== Export ==============================
 | ||||
| export default genComponentStyleHook( | ||||
|   'Message', | ||||
|   token => { | ||||
|     // Gen-style functions here
 | ||||
|     const combinedToken = mergeToken<MessageToken>(token, { | ||||
|       messageNoticeContentPadding: `${ | ||||
|         (token.controlHeightLG - token.fontSize * token.lineHeight) / 2 | ||||
|       }px ${token.paddingSM}px`,
 | ||||
|     }); | ||||
|     return [genMessageStyle(combinedToken)]; | ||||
|   }, | ||||
|   token => ({ | ||||
|     height: 150, | ||||
|     zIndexPopup: token.zIndexPopupBase + 10, | ||||
|   }), | ||||
| ); | ||||
|  | @ -1,2 +0,0 @@ | |||
| import '../../style/index.less'; | ||||
| import './index.less'; | ||||
|  | @ -1,17 +0,0 @@ | |||
| @import '../../style/themes/index'; | ||||
| @import '../../style/mixins/index'; | ||||
| 
 | ||||
| @message-prefix-cls: ~'@{ant-prefix}-message'; | ||||
| 
 | ||||
| .@{message-prefix-cls}-rtl { | ||||
|   direction: rtl; | ||||
| 
 | ||||
|   span { | ||||
|     direction: rtl; | ||||
|   } | ||||
| 
 | ||||
|   .@{iconfont-css-prefix} { | ||||
|     margin-right: 0; | ||||
|     margin-left: 8px; | ||||
|   } | ||||
| } | ||||
|  | @ -10,7 +10,7 @@ import { renderHelper } from '../_util/util'; | |||
| import { globalConfig } from '../config-provider'; | ||||
| import type { NotificationInstance as VCNotificationInstance } from '../vc-notification/Notification'; | ||||
| import classNames from '../_util/classNames'; | ||||
| 
 | ||||
| import useStyle from './style'; | ||||
| export type NotificationPlacement = | ||||
|   | 'top' | ||||
|   | 'topLeft' | ||||
|  | @ -163,6 +163,7 @@ function getNotificationInstance( | |||
|     { | ||||
|       name: 'notification', | ||||
|       prefixCls: customizePrefixCls || defaultPrefixCls, | ||||
|       useStyle, | ||||
|       class: notificationClass, | ||||
|       style: getPlacementStyle(placement, top, bottom), | ||||
|       appContext, | ||||
|  |  | |||
|  | @ -1,207 +0,0 @@ | |||
| @import '../../style/themes/index'; | ||||
| @import '../../style/mixins/index'; | ||||
| 
 | ||||
| .popover-customize-bg(@notification-prefix-cls, @popover-background); | ||||
| 
 | ||||
| @notification-prefix-cls: ~'@{ant-prefix}-notification'; | ||||
| @notification-width: 384px; | ||||
| @notification-padding: @notification-padding-vertical @notification-padding-horizontal; | ||||
| @notification-margin-bottom: 16px; | ||||
| @notification-margin-edge: 24px; | ||||
| 
 | ||||
| .@{notification-prefix-cls} { | ||||
|   .reset-component(); | ||||
| 
 | ||||
|   position: fixed; | ||||
|   z-index: @zindex-notification; | ||||
|   margin-right: @notification-margin-edge; | ||||
| 
 | ||||
|   &-close-icon { | ||||
|     font-size: @font-size-base; | ||||
|     cursor: pointer; | ||||
|   } | ||||
| 
 | ||||
|   &-hook-holder { | ||||
|     position: relative; | ||||
|   } | ||||
| 
 | ||||
|   &-notice { | ||||
|     position: relative; | ||||
|     width: @notification-width; | ||||
|     max-width: ~'calc(100vw - @{notification-margin-edge} * 2)'; | ||||
|     margin-bottom: @notification-margin-bottom; | ||||
|     margin-left: auto; | ||||
|     padding: @notification-padding; | ||||
|     overflow: hidden; | ||||
|     line-height: @line-height-base; | ||||
|     word-wrap: break-word; | ||||
|     background: @notification-bg; | ||||
|     border-radius: @border-radius-base; | ||||
|     box-shadow: @shadow-2; | ||||
| 
 | ||||
|     .@{notification-prefix-cls}-top &, | ||||
|     .@{notification-prefix-cls}-bottom & { | ||||
|       margin-right: auto; | ||||
|       margin-left: auto; | ||||
|     } | ||||
| 
 | ||||
|     .@{notification-prefix-cls}-topLeft &, | ||||
|     .@{notification-prefix-cls}-bottomLeft & { | ||||
|       margin-right: auto; | ||||
|       margin-left: 0; | ||||
|     } | ||||
| 
 | ||||
|     &-message { | ||||
|       margin-bottom: 8px; | ||||
|       color: @heading-color; | ||||
|       font-size: @font-size-lg; | ||||
|       line-height: 24px; | ||||
| 
 | ||||
|       // https://github.com/ant-design/ant-design/issues/5846#issuecomment-296244140 | ||||
|       &-single-line-auto-margin { | ||||
|         display: block; | ||||
|         width: ~'calc(@{notification-width} - @{notification-padding-horizontal} * 2 - 24px - 48px - 100%)'; | ||||
|         max-width: 4px; | ||||
|         background-color: transparent; | ||||
|         pointer-events: none; | ||||
| 
 | ||||
|         &::before { | ||||
|           display: block; | ||||
|           content: ''; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &-description { | ||||
|       font-size: @font-size-base; | ||||
|     } | ||||
| 
 | ||||
|     &-closable &-message { | ||||
|       padding-right: 24px; | ||||
|     } | ||||
| 
 | ||||
|     &-with-icon &-message { | ||||
|       margin-bottom: 4px; | ||||
|       margin-left: 48px; | ||||
|       font-size: @font-size-lg; | ||||
|     } | ||||
| 
 | ||||
|     &-with-icon &-description { | ||||
|       margin-left: 48px; | ||||
|       font-size: @font-size-base; | ||||
|     } | ||||
| 
 | ||||
|     // Icon & color style in different selector level | ||||
|     // https://github.com/ant-design/ant-design/issues/16503 | ||||
|     // https://github.com/ant-design/ant-design/issues/15512 | ||||
|     &-icon { | ||||
|       position: absolute; | ||||
|       margin-left: 4px; | ||||
|       font-size: 24px; | ||||
|       line-height: 24px; | ||||
|     } | ||||
| 
 | ||||
|     .@{iconfont-css-prefix}&-icon { | ||||
|       &-success { | ||||
|         color: @success-color; | ||||
|       } | ||||
| 
 | ||||
|       &-info { | ||||
|         color: @info-color; | ||||
|       } | ||||
| 
 | ||||
|       &-warning { | ||||
|         color: @warning-color; | ||||
|       } | ||||
| 
 | ||||
|       &-error { | ||||
|         color: @error-color; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &-close { | ||||
|       position: absolute; | ||||
|       top: 16px; | ||||
|       right: 22px; | ||||
|       color: @text-color-secondary; | ||||
|       outline: none; | ||||
| 
 | ||||
|       &:hover { | ||||
|         & when (@theme = dark) { | ||||
|           color: fade(@white, 85%); | ||||
|         } | ||||
|         & when not (@theme = dark) { | ||||
|           color: shade(@text-color-secondary, 40%); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &-btn { | ||||
|       float: right; | ||||
|       margin-top: 16px; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .notification-fade-effect { | ||||
|     animation-duration: 0.24s; | ||||
|     animation-timing-function: @ease-in-out; | ||||
|     animation-fill-mode: both; | ||||
|   } | ||||
| 
 | ||||
|   &-fade-enter, | ||||
|   &-fade-appear { | ||||
|     .notification-fade-effect(); | ||||
| 
 | ||||
|     opacity: 0; | ||||
|     animation-play-state: paused; | ||||
|   } | ||||
| 
 | ||||
|   &-fade-leave { | ||||
|     .notification-fade-effect(); | ||||
| 
 | ||||
|     animation-duration: 0.2s; | ||||
|     animation-play-state: paused; | ||||
|   } | ||||
| 
 | ||||
|   &-fade-enter&-fade-enter-active, | ||||
|   &-fade-appear&-fade-appear-active { | ||||
|     animation-name: NotificationFadeIn; | ||||
|     animation-play-state: running; | ||||
|   } | ||||
| 
 | ||||
|   &-fade-leave&-fade-leave-active { | ||||
|     animation-name: NotificationFadeOut; | ||||
|     animation-play-state: running; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @keyframes NotificationFadeIn { | ||||
|   0% { | ||||
|     left: @notification-width; | ||||
|     opacity: 0; | ||||
|   } | ||||
| 
 | ||||
|   100% { | ||||
|     left: 0; | ||||
|     opacity: 1; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @keyframes NotificationFadeOut { | ||||
|   0% { | ||||
|     max-height: 150px; | ||||
|     margin-bottom: @notification-margin-bottom; | ||||
|     opacity: 1; | ||||
|   } | ||||
| 
 | ||||
|   100% { | ||||
|     max-height: 0; | ||||
|     margin-bottom: 0; | ||||
|     padding-top: 0; | ||||
|     padding-bottom: 0; | ||||
|     opacity: 0; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @import './rtl'; | ||||
| @import './placement'; | ||||
|  | @ -0,0 +1,287 @@ | |||
| import { Keyframes } from '../../_util/cssinjs'; | ||||
| import type { FullToken, GenerateStyle } from '../../theme/internal'; | ||||
| import { genComponentStyleHook, mergeToken } from '../../theme/internal'; | ||||
| import genNotificationPlacementStyle from './placement'; | ||||
| import { resetComponent } from '../../_style'; | ||||
| 
 | ||||
| /** Component only token. Which will handle additional calculation of alias token */ | ||||
| export interface ComponentToken { | ||||
|   zIndexPopup: number; | ||||
|   width: number; | ||||
| } | ||||
| 
 | ||||
| export interface NotificationToken extends FullToken<'Notification'> { | ||||
|   notificationBg: string; | ||||
|   notificationPaddingVertical: number; | ||||
|   notificationPaddingHorizontal: number; | ||||
|   notificationPadding: string; | ||||
|   notificationMarginBottom: number; | ||||
|   notificationMarginEdge: number; | ||||
|   animationMaxHeight: number; | ||||
|   notificationIconSize: number; | ||||
|   notificationCloseButtonSize: number; | ||||
| } | ||||
| 
 | ||||
| const genNotificationStyle: GenerateStyle<NotificationToken> = token => { | ||||
|   const { | ||||
|     iconCls, | ||||
|     componentCls, // .ant-notification
 | ||||
|     boxShadowSecondary, | ||||
|     fontSizeLG, | ||||
|     notificationMarginBottom, | ||||
|     borderRadiusLG, | ||||
|     colorSuccess, | ||||
|     colorInfo, | ||||
|     colorWarning, | ||||
|     colorError, | ||||
|     colorTextHeading, | ||||
|     notificationBg, | ||||
|     notificationPadding, | ||||
|     notificationMarginEdge, | ||||
|     motionDurationMid, | ||||
|     motionEaseInOut, | ||||
|     fontSize, | ||||
|     lineHeight, | ||||
|     width, | ||||
|     notificationIconSize, | ||||
|   } = token; | ||||
| 
 | ||||
|   const noticeCls = `${componentCls}-notice`; | ||||
| 
 | ||||
|   const notificationFadeIn = new Keyframes('antNotificationFadeIn', { | ||||
|     '0%': { | ||||
|       left: { | ||||
|         _skip_check_: true, | ||||
|         value: width, | ||||
|       }, | ||||
|       opacity: 0, | ||||
|     }, | ||||
| 
 | ||||
|     '100%': { | ||||
|       left: { | ||||
|         _skip_check_: true, | ||||
|         value: 0, | ||||
|       }, | ||||
|       opacity: 1, | ||||
|     }, | ||||
|   }); | ||||
| 
 | ||||
|   const notificationFadeOut = new Keyframes('antNotificationFadeOut', { | ||||
|     '0%': { | ||||
|       maxHeight: token.animationMaxHeight, | ||||
|       marginBottom: notificationMarginBottom, | ||||
|       opacity: 1, | ||||
|     }, | ||||
| 
 | ||||
|     '100%': { | ||||
|       maxHeight: 0, | ||||
|       marginBottom: 0, | ||||
|       paddingTop: 0, | ||||
|       paddingBottom: 0, | ||||
|       opacity: 0, | ||||
|     }, | ||||
|   }); | ||||
| 
 | ||||
|   return [ | ||||
|     // ============================ Holder ============================
 | ||||
|     { | ||||
|       [componentCls]: { | ||||
|         ...resetComponent(token), | ||||
| 
 | ||||
|         position: 'fixed', | ||||
|         zIndex: token.zIndexPopup, | ||||
|         marginInlineEnd: notificationMarginEdge, | ||||
| 
 | ||||
|         [`${componentCls}-hook-holder`]: { | ||||
|           position: 'relative', | ||||
|         }, | ||||
| 
 | ||||
|         [`&${componentCls}-top, &${componentCls}-bottom`]: { | ||||
|           [`${componentCls}-notice`]: { | ||||
|             marginInline: 'auto auto', | ||||
|           }, | ||||
|         }, | ||||
| 
 | ||||
|         [`&${componentCls}-topLeft, &${componentCls}-bottomLeft`]: { | ||||
|           [`${componentCls}-notice`]: { | ||||
|             marginInlineEnd: 'auto', | ||||
|             marginInlineStart: 0, | ||||
|           }, | ||||
|         }, | ||||
| 
 | ||||
|         //  animation
 | ||||
|         [`${componentCls}-fade-enter, ${componentCls}-fade-appear`]: { | ||||
|           animationDuration: token.motionDurationMid, | ||||
|           animationTimingFunction: motionEaseInOut, | ||||
|           animationFillMode: 'both', | ||||
|           opacity: 0, | ||||
|           animationPlayState: 'paused', | ||||
|         }, | ||||
| 
 | ||||
|         [`${componentCls}-fade-leave`]: { | ||||
|           animationTimingFunction: motionEaseInOut, | ||||
|           animationFillMode: 'both', | ||||
| 
 | ||||
|           animationDuration: motionDurationMid, | ||||
|           animationPlayState: 'paused', | ||||
|         }, | ||||
| 
 | ||||
|         [`${componentCls}-fade-enter${componentCls}-fade-enter-active, ${componentCls}-fade-appear${componentCls}-fade-appear-active`]: | ||||
|           { | ||||
|             animationName: notificationFadeIn, | ||||
|             animationPlayState: 'running', | ||||
|           }, | ||||
| 
 | ||||
|         [`${componentCls}-fade-leave${componentCls}-fade-leave-active`]: { | ||||
|           animationName: notificationFadeOut, | ||||
|           animationPlayState: 'running', | ||||
|         }, | ||||
| 
 | ||||
|         // placement
 | ||||
|         ...genNotificationPlacementStyle(token), | ||||
| 
 | ||||
|         // RTL
 | ||||
|         '&-rtl': { | ||||
|           direction: 'rtl', | ||||
| 
 | ||||
|           [`${componentCls}-notice-btn`]: { | ||||
|             float: 'left', | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
| 
 | ||||
|     // ============================ Notice ============================
 | ||||
|     { | ||||
|       [noticeCls]: { | ||||
|         position: 'relative', | ||||
|         width, | ||||
|         maxWidth: `calc(100vw - ${notificationMarginEdge * 2}px)`, | ||||
|         marginBottom: notificationMarginBottom, | ||||
|         marginInlineStart: 'auto', | ||||
|         padding: notificationPadding, | ||||
|         overflow: 'hidden', | ||||
|         lineHeight, | ||||
|         wordWrap: 'break-word', | ||||
|         background: notificationBg, | ||||
|         borderRadius: borderRadiusLG, | ||||
|         boxShadow: boxShadowSecondary, | ||||
| 
 | ||||
|         [`${componentCls}-close-icon`]: { | ||||
|           fontSize, | ||||
|           cursor: 'pointer', | ||||
|         }, | ||||
| 
 | ||||
|         [`${noticeCls}-message`]: { | ||||
|           marginBottom: token.marginXS, | ||||
|           color: colorTextHeading, | ||||
|           fontSize: fontSizeLG, | ||||
|           lineHeight: token.lineHeightLG, | ||||
|         }, | ||||
| 
 | ||||
|         [`${noticeCls}-description`]: { | ||||
|           fontSize, | ||||
|         }, | ||||
| 
 | ||||
|         [`&${noticeCls}-closable ${noticeCls}-message`]: { | ||||
|           paddingInlineEnd: token.paddingLG, | ||||
|         }, | ||||
| 
 | ||||
|         [`${noticeCls}-with-icon ${noticeCls}-message`]: { | ||||
|           marginBottom: token.marginXS, | ||||
|           marginInlineStart: token.marginSM + notificationIconSize, | ||||
|           fontSize: fontSizeLG, | ||||
|         }, | ||||
| 
 | ||||
|         [`${noticeCls}-with-icon ${noticeCls}-description`]: { | ||||
|           marginInlineStart: token.marginSM + notificationIconSize, | ||||
|           fontSize, | ||||
|         }, | ||||
| 
 | ||||
|         // Icon & color style in different selector level
 | ||||
|         // https://github.com/ant-design/ant-design/issues/16503
 | ||||
|         // https://github.com/ant-design/ant-design/issues/15512
 | ||||
|         [`${noticeCls}-icon`]: { | ||||
|           position: 'absolute', | ||||
|           fontSize: notificationIconSize, | ||||
|           lineHeight: 0, | ||||
| 
 | ||||
|           // icon-font
 | ||||
|           [`&-success${iconCls}`]: { | ||||
|             color: colorSuccess, | ||||
|           }, | ||||
|           [`&-info${iconCls}`]: { | ||||
|             color: colorInfo, | ||||
|           }, | ||||
|           [`&-warning${iconCls}`]: { | ||||
|             color: colorWarning, | ||||
|           }, | ||||
|           [`&-error${iconCls}`]: { | ||||
|             color: colorError, | ||||
|           }, | ||||
|         }, | ||||
| 
 | ||||
|         [`${noticeCls}-close`]: { | ||||
|           position: 'absolute', | ||||
|           top: token.notificationPaddingVertical, | ||||
|           insetInlineEnd: token.notificationPaddingHorizontal, | ||||
|           color: token.colorIcon, | ||||
|           outline: 'none', | ||||
|           width: token.notificationCloseButtonSize, | ||||
|           height: token.notificationCloseButtonSize, | ||||
|           borderRadius: token.borderRadiusSM, | ||||
|           transition: `background-color ${token.motionDurationMid}, color ${token.motionDurationMid}`, | ||||
|           display: 'flex', | ||||
|           alignItems: 'center', | ||||
|           justifyContent: 'center', | ||||
| 
 | ||||
|           '&:hover': { | ||||
|             color: token.colorIconHover, | ||||
|             backgroundColor: token.wireframe ? 'transparent' : token.colorFillContent, | ||||
|           }, | ||||
|         }, | ||||
| 
 | ||||
|         [`${noticeCls}-btn`]: { | ||||
|           float: 'right', | ||||
|           marginTop: token.marginSM, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
| 
 | ||||
|     // ============================= Pure =============================
 | ||||
|     { | ||||
|       [`${noticeCls}-pure-panel`]: { | ||||
|         margin: 0, | ||||
|       }, | ||||
|     }, | ||||
|   ]; | ||||
| }; | ||||
| 
 | ||||
| // ============================== Export ==============================
 | ||||
| export default genComponentStyleHook( | ||||
|   'Notification', | ||||
|   token => { | ||||
|     const notificationPaddingVertical = token.paddingMD; | ||||
|     const notificationPaddingHorizontal = token.paddingLG; | ||||
| 
 | ||||
|     const notificationToken = mergeToken<NotificationToken>(token, { | ||||
|       // default.less variables
 | ||||
|       notificationBg: token.colorBgElevated, | ||||
|       notificationPaddingVertical, | ||||
|       notificationPaddingHorizontal, | ||||
|       // index.less variables
 | ||||
|       notificationPadding: `${token.paddingMD}px ${token.paddingContentHorizontalLG}px`, | ||||
|       notificationMarginBottom: token.margin, | ||||
|       notificationMarginEdge: token.marginLG, | ||||
|       animationMaxHeight: 150, | ||||
|       notificationIconSize: token.fontSizeLG * token.lineHeightLG, | ||||
|       notificationCloseButtonSize: token.controlHeightLG * 0.55, | ||||
|     }); | ||||
| 
 | ||||
|     return [genNotificationStyle(notificationToken)]; | ||||
|   }, | ||||
|   token => ({ | ||||
|     zIndexPopup: token.zIndexPopupBase + 50, | ||||
|     width: 384, | ||||
|   }), | ||||
| ); | ||||
|  | @ -1,2 +0,0 @@ | |||
| import '../../style/index.less'; | ||||
| import './index.less'; | ||||
|  | @ -1,68 +0,0 @@ | |||
| .@{notification-prefix-cls} { | ||||
|   &-top, | ||||
|   &-bottom { | ||||
|     margin-right: 0; | ||||
|     margin-left: 0; | ||||
|   } | ||||
| 
 | ||||
|   &-top { | ||||
|     .@{notification-prefix-cls}-fade-enter.@{notification-prefix-cls}-fade-enter-active, | ||||
|     .@{notification-prefix-cls}-fade-appear.@{notification-prefix-cls}-fade-appear-active { | ||||
|       animation-name: NotificationTopFadeIn; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-bottom { | ||||
|     .@{notification-prefix-cls}-fade-enter.@{notification-prefix-cls}-fade-enter-active, | ||||
|     .@{notification-prefix-cls}-fade-appear.@{notification-prefix-cls}-fade-appear-active { | ||||
|       animation-name: NotificationBottomFadeIn; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-topLeft, | ||||
|   &-bottomLeft { | ||||
|     margin-right: 0; | ||||
|     margin-left: @notification-margin-edge; | ||||
| 
 | ||||
|     .@{notification-prefix-cls}-fade-enter.@{notification-prefix-cls}-fade-enter-active, | ||||
|     .@{notification-prefix-cls}-fade-appear.@{notification-prefix-cls}-fade-appear-active { | ||||
|       animation-name: NotificationLeftFadeIn; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @keyframes NotificationTopFadeIn { | ||||
|   0% { | ||||
|     margin-top: -100%; | ||||
|     opacity: 0; | ||||
|   } | ||||
| 
 | ||||
|   100% { | ||||
|     margin-top: 0; | ||||
|     opacity: 1; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @keyframes NotificationBottomFadeIn { | ||||
|   0% { | ||||
|     margin-bottom: -100%; | ||||
|     opacity: 0; | ||||
|   } | ||||
| 
 | ||||
|   100% { | ||||
|     margin-bottom: 0; | ||||
|     opacity: 1; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @keyframes NotificationLeftFadeIn { | ||||
|   0% { | ||||
|     right: @notification-width; | ||||
|     opacity: 0; | ||||
|   } | ||||
| 
 | ||||
|   100% { | ||||
|     right: 0; | ||||
|     opacity: 1; | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,81 @@ | |||
| import type { CSSObject } from '../../_util/cssinjs'; | ||||
| import { Keyframes } from '../../_util/cssinjs'; | ||||
| import type { NotificationToken } from '.'; | ||||
| import type { GenerateStyle } from '../../theme/internal'; | ||||
| 
 | ||||
| const genNotificationPlacementStyle: GenerateStyle<NotificationToken, CSSObject> = token => { | ||||
|   const { componentCls, width, notificationMarginEdge } = token; | ||||
| 
 | ||||
|   const notificationTopFadeIn = new Keyframes('antNotificationTopFadeIn', { | ||||
|     '0%': { | ||||
|       marginTop: '-100%', | ||||
|       opacity: 0, | ||||
|     }, | ||||
| 
 | ||||
|     '100%': { | ||||
|       marginTop: 0, | ||||
|       opacity: 1, | ||||
|     }, | ||||
|   }); | ||||
| 
 | ||||
|   const notificationBottomFadeIn = new Keyframes('antNotificationBottomFadeIn', { | ||||
|     '0%': { | ||||
|       marginBottom: '-100%', | ||||
|       opacity: 0, | ||||
|     }, | ||||
| 
 | ||||
|     '100%': { | ||||
|       marginBottom: 0, | ||||
|       opacity: 1, | ||||
|     }, | ||||
|   }); | ||||
| 
 | ||||
|   const notificationLeftFadeIn = new Keyframes('antNotificationLeftFadeIn', { | ||||
|     '0%': { | ||||
|       right: { | ||||
|         _skip_check_: true, | ||||
|         value: width, | ||||
|       }, | ||||
|       opacity: 0, | ||||
|     }, | ||||
| 
 | ||||
|     '100%': { | ||||
|       right: { | ||||
|         _skip_check_: true, | ||||
|         value: 0, | ||||
|       }, | ||||
|       opacity: 1, | ||||
|     }, | ||||
|   }); | ||||
| 
 | ||||
|   return { | ||||
|     [`&${componentCls}-top, &${componentCls}-bottom`]: { | ||||
|       marginInline: 0, | ||||
|     }, | ||||
| 
 | ||||
|     [`&${componentCls}-top`]: { | ||||
|       [`${componentCls}-fade-enter${componentCls}-fade-enter-active, ${componentCls}-fade-appear${componentCls}-fade-appear-active`]: | ||||
|         { | ||||
|           animationName: notificationTopFadeIn, | ||||
|         }, | ||||
|     }, | ||||
| 
 | ||||
|     [`&${componentCls}-bottom`]: { | ||||
|       [`${componentCls}-fade-enter${componentCls}-fade-enter-active, ${componentCls}-fade-appear${componentCls}-fade-appear-active`]: | ||||
|         { | ||||
|           animationName: notificationBottomFadeIn, | ||||
|         }, | ||||
|     }, | ||||
| 
 | ||||
|     [`&${componentCls}-topLeft, &${componentCls}-bottomLeft`]: { | ||||
|       marginInlineEnd: 0, | ||||
|       marginInlineStart: notificationMarginEdge, | ||||
| 
 | ||||
|       [`${componentCls}-fade-enter${componentCls}-fade-enter-active, ${componentCls}-fade-appear${componentCls}-fade-appear-active`]: | ||||
|         { | ||||
|           animationName: notificationLeftFadeIn, | ||||
|         }, | ||||
|     }, | ||||
|   }; | ||||
| }; | ||||
| export default genNotificationPlacementStyle; | ||||
|  | @ -1,53 +0,0 @@ | |||
| @import '../../style/themes/index'; | ||||
| @import '../../style/mixins/index'; | ||||
| 
 | ||||
| @notification-prefix-cls: ~'@{ant-prefix}-notification'; | ||||
| 
 | ||||
| .@{notification-prefix-cls} { | ||||
|   &-rtl { | ||||
|     direction: rtl; | ||||
|   } | ||||
| 
 | ||||
|   &-notice { | ||||
|     &-closable &-message { | ||||
|       .@{notification-prefix-cls}-rtl & { | ||||
|         padding-right: 0; | ||||
|         padding-left: 24px; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &-with-icon &-message { | ||||
|       .@{notification-prefix-cls}-rtl & { | ||||
|         margin-right: 48px; | ||||
|         margin-left: 0; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &-with-icon &-description { | ||||
|       .@{notification-prefix-cls}-rtl & { | ||||
|         margin-right: 48px; | ||||
|         margin-left: 0; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &-icon { | ||||
|       .@{notification-prefix-cls}-rtl & { | ||||
|         margin-right: 4px; | ||||
|         margin-left: 0; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &-close { | ||||
|       .@{notification-prefix-cls}-rtl & { | ||||
|         right: auto; | ||||
|         left: 22px; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &-btn { | ||||
|       .@{notification-prefix-cls}-rtl & { | ||||
|         float: left; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -20,8 +20,8 @@ import './divider/style'; | |||
| import './card/style'; | ||||
| import './collapse/style'; | ||||
| import './carousel/style'; | ||||
| import './notification/style'; | ||||
| import './message/style'; | ||||
| // import './notification/style';
 | ||||
| // import './message/style';
 | ||||
| import './spin/style'; | ||||
| import './select/style'; | ||||
| import './switch/style'; | ||||
|  |  | |||
|  | @ -21,9 +21,9 @@ import type { ComponentToken as ButtonComponentToken } from '../../button/style' | |||
| // import type { ComponentToken as ListComponentToken } from '../../list/style';
 | ||||
| // import type { ComponentToken as MentionsComponentToken } from '../../mentions/style';
 | ||||
| // import type { ComponentToken as MenuComponentToken } from '../../menu/style';
 | ||||
| // import type { ComponentToken as MessageComponentToken } from '../../message/style';
 | ||||
| import type { ComponentToken as MessageComponentToken } from '../../message/style'; | ||||
| // import type { ComponentToken as ModalComponentToken } from '../../modal/style';
 | ||||
| // import type { ComponentToken as NotificationComponentToken } from '../../notification/style';
 | ||||
| import type { ComponentToken as NotificationComponentToken } from '../../notification/style'; | ||||
| // import type { ComponentToken as PopconfirmComponentToken } from '../../popconfirm/style';
 | ||||
| // import type { ComponentToken as PopoverComponentToken } from '../../popover/style';
 | ||||
| // import type { ComponentToken as ProgressComponentToken } from '../../progress/style';
 | ||||
|  | @ -79,7 +79,7 @@ export interface ComponentTokenMap { | |||
|   //   Layout?: LayoutComponentToken;
 | ||||
|   //   List?: ListComponentToken;
 | ||||
|   //   Mentions?: MentionsComponentToken;
 | ||||
|   //   Notification?: NotificationComponentToken;
 | ||||
|   Notification?: NotificationComponentToken; | ||||
|   Pagination?: {}; | ||||
|   //   Popover?: PopoverComponentToken;
 | ||||
|   //   Popconfirm?: PopconfirmComponentToken;
 | ||||
|  | @ -104,7 +104,7 @@ export interface ComponentTokenMap { | |||
|   //   Steps?: StepsComponentToken;
 | ||||
|   //   Menu?: MenuComponentToken;
 | ||||
|   //   Modal?: ModalComponentToken;
 | ||||
|   //   Message?: MessageComponentToken;
 | ||||
|   Message?: MessageComponentToken; | ||||
|   //   Upload?: UploadComponentToken;
 | ||||
|   //   Tooltip?: TooltipComponentToken;
 | ||||
|   //   Table?: TableComponentToken;
 | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ import { | |||
| import type { NoticeProps } from './Notice'; | ||||
| import Notice from './Notice'; | ||||
| import ConfigProvider, { globalConfigForApi } from '../config-provider'; | ||||
| import classNames from '../_util/classNames'; | ||||
| 
 | ||||
| let seed = 0; | ||||
| const now = Date.now(); | ||||
|  | @ -52,6 +53,7 @@ export interface NotificationProps { | |||
|   animation?: string | object; | ||||
|   maxCount?: number; | ||||
|   closeIcon?: any; | ||||
|   hashId?: string; | ||||
| } | ||||
| 
 | ||||
| type NotificationState = { | ||||
|  | @ -64,7 +66,7 @@ type NotificationState = { | |||
| const Notification = defineComponent<NotificationProps>({ | ||||
|   name: 'Notification', | ||||
|   inheritAttrs: false, | ||||
|   props: ['prefixCls', 'transitionName', 'animation', 'maxCount', 'closeIcon'] as any, | ||||
|   props: ['prefixCls', 'transitionName', 'animation', 'maxCount', 'closeIcon', 'hashId'] as any, | ||||
|   setup(props, { attrs, expose, slots }) { | ||||
|     const hookRefs = new Map<Key, HTMLDivElement>(); | ||||
|     const notices = ref<NotificationState>([]); | ||||
|  | @ -166,7 +168,7 @@ const Notification = defineComponent<NotificationProps>({ | |||
|           ); | ||||
|         } | ||||
|         return ( | ||||
|           <Notice {...noticeProps}> | ||||
|           <Notice {...noticeProps} class={classNames(noticeProps.class, props.hashId)}> | ||||
|             {typeof content === 'function' ? content({ prefixCls }) : content} | ||||
|           </Notice> | ||||
|         ); | ||||
|  | @ -174,6 +176,7 @@ const Notification = defineComponent<NotificationProps>({ | |||
|       const className = { | ||||
|         [prefixCls]: 1, | ||||
|         [attrs.class as string]: !!attrs.class, | ||||
|         [props.hashId]: true, | ||||
|       }; | ||||
|       return ( | ||||
|         <div | ||||
|  | @ -203,6 +206,7 @@ Notification.newInstance = function newNotificationInstance(properties, callback | |||
|     rootPrefixCls: customRootPrefixCls, | ||||
|     transitionName: customTransitionName, | ||||
|     hasTransitionName, | ||||
|     useStyle, | ||||
|     ...props | ||||
|   } = properties || {}; | ||||
|   const div = document.createElement('div'); | ||||
|  | @ -217,6 +221,8 @@ Notification.newInstance = function newNotificationInstance(properties, callback | |||
|     name: 'NotificationWrapper', | ||||
|     setup(_props, { attrs }) { | ||||
|       const notiRef = ref(); | ||||
|       const prefixCls = computed(() => globalConfigForApi.getPrefixCls(name, customizePrefixCls)); | ||||
|       const [, hashId] = useStyle(prefixCls); | ||||
|       onMounted(() => { | ||||
|         callback({ | ||||
|           notice(noticeProps: NoticeContent) { | ||||
|  | @ -236,8 +242,7 @@ Notification.newInstance = function newNotificationInstance(properties, callback | |||
|       }); | ||||
|       return () => { | ||||
|         const global = globalConfigForApi; | ||||
|         const prefixCls = global.getPrefixCls(name, customizePrefixCls); | ||||
|         const rootPrefixCls = global.getRootPrefixCls(customRootPrefixCls, prefixCls); | ||||
|         const rootPrefixCls = global.getRootPrefixCls(customRootPrefixCls, prefixCls.value); | ||||
|         const transitionName = hasTransitionName | ||||
|           ? customTransitionName | ||||
|           : `${rootPrefixCls}-${customTransitionName}`; | ||||
|  | @ -246,8 +251,9 @@ Notification.newInstance = function newNotificationInstance(properties, callback | |||
|             <Notification | ||||
|               ref={notiRef} | ||||
|               {...attrs} | ||||
|               prefixCls={prefixCls} | ||||
|               prefixCls={prefixCls.value} | ||||
|               transitionName={transitionName} | ||||
|               hashId={hashId.value} | ||||
|             /> | ||||
|           </ConfigProvider> | ||||
|         ); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 tangjinzhou
						tangjinzhou