feat: CP support Notification className and style (#43328)

* feat: CP support Notification className and style

* Update components/config-provider/index.en-US.md

Co-authored-by: MadCcc <1075746765@qq.com>
Signed-off-by: lijianan <574980606@qq.com>

* fix

* fix

* test

---------

Signed-off-by: lijianan <574980606@qq.com>
Co-authored-by: MadCcc <1075746765@qq.com>
This commit is contained in:
lijianan 2023-07-03 20:37:11 +08:00 committed by GitHub
parent 62dd62f43c
commit c267b38fd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 52 additions and 24 deletions

View File

@ -1,6 +1,6 @@
import React from 'react';
import ConfigProvider from '..';
import { render } from '../../../tests/utils';
import { fireEvent, render } from '../../../tests/utils';
import Anchor from '../../anchor';
import Avatar from '../../avatar';
import Badge from '../../badge';
@ -17,6 +17,7 @@ import Input from '../../input';
import Layout from '../../layout';
import Mentions from '../../mentions';
import Modal from '../../modal';
import notification from '../../notification';
import Pagination from '../../pagination';
import Radio from '../../radio';
import Rate from '../../rate';
@ -677,4 +678,25 @@ describe('ConfigProvider support style and className props', () => {
expect(element).toHaveClass('cp-upload');
expect(element?.querySelector<HTMLDivElement>('.ant-upload')).toHaveStyle({ color: 'blue' });
});
it('Should notification className & style works', () => {
const Demo: React.FC = () => {
const [api, holder] = notification.useNotification();
return (
<ConfigProvider notification={{ className: 'cp-notification', style: { color: 'blue' } }}>
<button type="button" onClick={() => api.open({ message: 'test', duration: 0 })}>
test
</button>
{holder}
</ConfigProvider>
);
};
const { container } = render(<Demo />);
fireEvent.click(container.querySelector<HTMLButtonElement>('button')!);
const element = document
?.querySelector<HTMLDivElement>('.ant-notification')
?.querySelector<HTMLDivElement>('.ant-notification-notice');
expect(element).toHaveClass('cp-notification');
expect(element).toHaveStyle({ color: 'blue' });
});
});

View File

@ -122,6 +122,7 @@ export interface ConfigConsumerProps {
card?: ComponentStyleConfig;
tabs?: ComponentStyleConfig;
upload?: ComponentStyleConfig;
notification?: ComponentStyleConfig;
}
const defaultGetPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => {

View File

@ -118,6 +118,7 @@ const {
| layout | Set Layout common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| mentions | Set Mentions common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| modal | Set Modal common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| notification | Set Notification common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| pagination | Set Pagination common props | { showSizeChanger?: boolean, className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| radio | Set Radio common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| rate | Set Rate common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |

View File

@ -166,6 +166,7 @@ export interface ConfigProviderProps {
card?: ComponentStyleConfig;
tabs?: ComponentStyleConfig;
upload?: ComponentStyleConfig;
notification?: ComponentStyleConfig;
}
interface ProviderChildrenProps extends ConfigProviderProps {
@ -284,6 +285,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {
card,
tabs,
upload,
notification,
} = props;
// =================================== Warning ===================================
@ -364,6 +366,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {
card,
tabs,
upload,
notification,
};
const config = {

View File

@ -120,6 +120,7 @@ const {
| layout | 设置 Layout 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| mentions | 设置 Mentions 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| modal | 设置 Modal 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| notification | 设置 Notification 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| pagination | 设置 Pagination 组件的通用属性 | { showSizeChanger?: boolean, className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| radio | 设置 Radio 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| rate | 设置 Rate 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |

View File

@ -48,15 +48,8 @@ const typeToIcon = {
warning: ExclamationCircleFilled,
};
export function PureContent({
prefixCls,
icon,
type,
message,
description,
btn,
role = 'alert',
}: PureContentProps) {
export const PureContent: React.FC<PureContentProps> = (props) => {
const { prefixCls, icon, type, message, description, btn, role = 'alert' } = props;
let iconNode: React.ReactNode = null;
if (icon) {
iconNode = <span className={`${prefixCls}-icon`}>{icon}</span>;
@ -65,21 +58,15 @@ export function PureContent({
className: classNames(`${prefixCls}-icon`, `${prefixCls}-icon-${type}`),
});
}
return (
<div
className={classNames({
[`${prefixCls}-with-icon`]: iconNode,
})}
role={role}
>
<div className={classNames({ [`${prefixCls}-with-icon`]: iconNode })} role={role}>
{iconNode}
<div className={`${prefixCls}-message`}>{message}</div>
<div className={`${prefixCls}-description`}>{description}</div>
{btn && <div className={`${prefixCls}-btn`}>{btn}</div>}
</div>
);
}
};
export interface PurePanelProps
extends Omit<NoticeProps, 'prefixCls' | 'eventKey'>,
@ -88,7 +75,7 @@ export interface PurePanelProps
}
/** @internal Internal Component. Do not use in your production. */
export default function PurePanel(props: PurePanelProps) {
const PurePanel: React.FC<PurePanelProps> = (props) => {
const {
prefixCls: staticPrefixCls,
className,
@ -129,4 +116,6 @@ export default function PurePanel(props: PurePanelProps) {
}
/>
);
}
};
export default PurePanel;

View File

@ -4,6 +4,7 @@ import type { NotificationAPI } from 'rc-notification/lib';
import * as React from 'react';
import warning from '../_util/warning';
import { ConfigContext } from '../config-provider';
import type { ComponentStyleConfig } from '../config-provider/context';
import { PureContent, getCloseIcon } from './PurePanel';
import type {
ArgsProps,
@ -27,6 +28,7 @@ type HolderProps = NotificationConfig & {
interface HolderRef extends NotificationAPI {
prefixCls: string;
hashId: string;
notification?: ComponentStyleConfig;
}
const Holder = React.forwardRef<HolderRef, HolderProps>((props, ref) => {
@ -39,12 +41,12 @@ const Holder = React.forwardRef<HolderRef, HolderProps>((props, ref) => {
rtl,
onAllRemoved,
} = props;
const { getPrefixCls, getPopupContainer } = React.useContext(ConfigContext);
const { getPrefixCls, getPopupContainer, notification } = React.useContext(ConfigContext);
const prefixCls = staticPrefixCls || getPrefixCls('notification');
// =============================== Style ===============================
const getStyle = (placement: NotificationPlacement) =>
const getStyle = (placement: NotificationPlacement): React.CSSProperties =>
getPlacementStyle(placement, top ?? DEFAULT_OFFSET, bottom ?? DEFAULT_OFFSET);
// Style
@ -74,6 +76,7 @@ const Holder = React.forwardRef<HolderRef, HolderProps>((props, ref) => {
...api,
prefixCls,
hashId,
notification,
}));
return holder;
@ -102,7 +105,8 @@ export function useInternalNotification(
return;
}
const { open: originOpen, prefixCls, hashId } = holderRef.current;
const { open: originOpen, prefixCls, hashId, notification } = holderRef.current;
const noticePrefixCls = `${prefixCls}-notice`;
const {
@ -112,6 +116,7 @@ export function useInternalNotification(
type,
btn,
className,
style,
role = 'alert',
closeIcon,
...restConfig
@ -133,7 +138,13 @@ export function useInternalNotification(
role={role}
/>
),
className: classNames(type && `${noticePrefixCls}-${type}`, hashId, className),
className: classNames(
type && `${noticePrefixCls}-${type}`,
hashId,
className,
notification?.className,
),
style: { ...notification?.style, ...style },
closeIcon: realCloseIcon,
closable: !!realCloseIcon,
});