From 73ce7088681c8f64c9c8ee0b9e324e1f48eb118f Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Fri, 27 Jan 2023 22:36:28 +0800 Subject: [PATCH] refactor: message & notification --- components/message/index.tsx | 2 + components/message/style/index.less | 74 ----- components/message/style/index.ts | 178 ++++++++++++ components/message/style/index.tsx | 2 - components/message/style/rtl.less | 17 -- components/notification/index.tsx | 3 +- components/notification/style/index.less | 207 ------------- components/notification/style/index.ts | 287 +++++++++++++++++++ components/notification/style/index.tsx | 2 - components/notification/style/placement.less | 68 ----- components/notification/style/placement.ts | 81 ++++++ components/notification/style/rtl.less | 53 ---- components/style.ts | 4 +- components/theme/interface/components.ts | 8 +- components/vc-notification/Notification.tsx | 16 +- 15 files changed, 567 insertions(+), 435 deletions(-) delete mode 100644 components/message/style/index.less create mode 100644 components/message/style/index.ts delete mode 100644 components/message/style/index.tsx delete mode 100644 components/message/style/rtl.less delete mode 100644 components/notification/style/index.less create mode 100644 components/notification/style/index.ts delete mode 100644 components/notification/style/index.tsx delete mode 100644 components/notification/style/placement.less create mode 100644 components/notification/style/placement.ts delete mode 100644 components/notification/style/rtl.less diff --git a/components/message/index.tsx b/components/message/index.tsx index 35e7c93aa..14ef956e3 100644 --- a/components/message/index.tsx +++ b/components/message/index.tsx @@ -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) { diff --git a/components/message/style/index.less b/components/message/style/index.less deleted file mode 100644 index 2594fff74..000000000 --- a/components/message/style/index.less +++ /dev/null @@ -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'; diff --git a/components/message/style/index.ts b/components/message/style/index.ts new file mode 100644 index 000000000..f9b9a3592 --- /dev/null +++ b/components/message/style/index.ts @@ -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 = 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(token, { + messageNoticeContentPadding: `${ + (token.controlHeightLG - token.fontSize * token.lineHeight) / 2 + }px ${token.paddingSM}px`, + }); + return [genMessageStyle(combinedToken)]; + }, + token => ({ + height: 150, + zIndexPopup: token.zIndexPopupBase + 10, + }), +); diff --git a/components/message/style/index.tsx b/components/message/style/index.tsx deleted file mode 100644 index 3a3ab0de5..000000000 --- a/components/message/style/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -import '../../style/index.less'; -import './index.less'; diff --git a/components/message/style/rtl.less b/components/message/style/rtl.less deleted file mode 100644 index 944803bd3..000000000 --- a/components/message/style/rtl.less +++ /dev/null @@ -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; - } -} diff --git a/components/notification/index.tsx b/components/notification/index.tsx index 164513981..e6fb47f2e 100644 --- a/components/notification/index.tsx +++ b/components/notification/index.tsx @@ -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, diff --git a/components/notification/style/index.less b/components/notification/style/index.less deleted file mode 100644 index ae0d0a674..000000000 --- a/components/notification/style/index.less +++ /dev/null @@ -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'; diff --git a/components/notification/style/index.ts b/components/notification/style/index.ts new file mode 100644 index 000000000..c3c74cb42 --- /dev/null +++ b/components/notification/style/index.ts @@ -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 = 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(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, + }), +); diff --git a/components/notification/style/index.tsx b/components/notification/style/index.tsx deleted file mode 100644 index 3a3ab0de5..000000000 --- a/components/notification/style/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -import '../../style/index.less'; -import './index.less'; diff --git a/components/notification/style/placement.less b/components/notification/style/placement.less deleted file mode 100644 index 9a60fecac..000000000 --- a/components/notification/style/placement.less +++ /dev/null @@ -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; - } -} diff --git a/components/notification/style/placement.ts b/components/notification/style/placement.ts new file mode 100644 index 000000000..09bb92c42 --- /dev/null +++ b/components/notification/style/placement.ts @@ -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 = 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; diff --git a/components/notification/style/rtl.less b/components/notification/style/rtl.less deleted file mode 100644 index 9285a25cc..000000000 --- a/components/notification/style/rtl.less +++ /dev/null @@ -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; - } - } - } -} diff --git a/components/style.ts b/components/style.ts index 9346bf82b..702feea80 100644 --- a/components/style.ts +++ b/components/style.ts @@ -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'; diff --git a/components/theme/interface/components.ts b/components/theme/interface/components.ts index 7f9aed313..d4f46a00a 100644 --- a/components/theme/interface/components.ts +++ b/components/theme/interface/components.ts @@ -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; diff --git a/components/vc-notification/Notification.tsx b/components/vc-notification/Notification.tsx index 1ada49c7a..0f422194e 100644 --- a/components/vc-notification/Notification.tsx +++ b/components/vc-notification/Notification.tsx @@ -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({ 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(); const notices = ref([]); @@ -166,7 +168,7 @@ const Notification = defineComponent({ ); } return ( - + {typeof content === 'function' ? content({ prefixCls }) : content} ); @@ -174,6 +176,7 @@ const Notification = defineComponent({ const className = { [prefixCls]: 1, [attrs.class as string]: !!attrs.class, + [props.hashId]: true, }; return (
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 );