Skip to content

Commit 7b7f520

Browse files
committed
refactor: inline notification list config handling
1 parent 6b14e0a commit 7b7f520

File tree

2 files changed

+95
-4
lines changed

2 files changed

+95
-4
lines changed

src/Notification.tsx

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,47 @@
11
import * as React from 'react';
2+
import { clsx } from 'clsx';
23
import useNoticeTimer from './hooks/useNoticeTimer';
34
import { useEvent } from '@rc-component/util';
45

6+
export interface NotificationClassNames {
7+
root?: string;
8+
close?: string;
9+
}
10+
11+
export interface NotificationStyles {
12+
root?: React.CSSProperties;
13+
close?: React.CSSProperties;
14+
}
15+
516
export interface NotificationProps {
617
content?: React.ReactNode;
718
actions?: React.ReactNode;
819
close?: React.ReactNode;
920
duration?: number | false;
1021
pauseOnHover?: boolean;
22+
className?: string;
23+
style?: React.CSSProperties;
24+
classNames?: NotificationClassNames;
25+
styles?: NotificationStyles;
1126
onClick?: React.MouseEventHandler<HTMLDivElement>;
1227
/** Callback when notification is closed by timeout */
1328
onClose?: () => void;
1429
}
1530

1631
const Notification = React.forwardRef<HTMLDivElement, NotificationProps>((props, ref) => {
17-
const { content, actions, close, duration = 4.5, pauseOnHover = true, onClick, onClose } = props;
32+
const {
33+
content,
34+
actions,
35+
close,
36+
duration = 4.5,
37+
pauseOnHover = true,
38+
className,
39+
style,
40+
classNames,
41+
styles,
42+
onClick,
43+
onClose,
44+
} = props;
1845

1946
// ========================= Close ==========================
2047
const onEventClose = useEvent(onClose);
@@ -26,15 +53,21 @@ const Notification = React.forwardRef<HTMLDivElement, NotificationProps>((props,
2653
return (
2754
<div
2855
ref={ref}
56+
className={clsx(className, classNames?.root)}
57+
style={{
58+
...styles?.root,
59+
...style,
60+
}}
2961
onClick={onClick}
3062
onMouseEnter={pauseOnHover ? onPause : undefined}
3163
onMouseLeave={pauseOnHover ? onResume : undefined}
3264
>
3365
{content}
3466
{close && (
3567
<button
36-
className="close"
68+
className={clsx('close', classNames?.close)}
3769
aria-label="Close"
70+
style={styles?.close}
3871
onClick={(e) => {
3972
e.stopPropagation();
4073
onEventClose();

src/NotificationList.tsx

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
import { CSSMotionList } from '@rc-component/motion';
12
import type { CSSMotionProps } from '@rc-component/motion';
3+
import { clsx } from 'clsx';
24
import * as React from 'react';
5+
import Notification, {
6+
type NotificationClassNames,
7+
type NotificationProps,
8+
type NotificationStyles,
9+
} from './Notification';
310

411
export type Placement = 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight';
512

@@ -11,18 +18,69 @@ export type StackConfig =
1118
gap?: number;
1219
};
1320

21+
export interface NotificationListConfig extends NotificationProps {
22+
key: React.Key;
23+
}
24+
1425
export interface NotificationListProps {
26+
configList?: NotificationListConfig[];
1527
prefixCls?: string;
1628
getContainer?: () => HTMLElement | ShadowRoot;
1729
placement?: Placement;
1830
pauseOnHover?: boolean;
31+
classNames?: NotificationClassNames;
32+
styles?: NotificationStyles;
1933
stack?: StackConfig;
2034
maxCount?: number;
2135
motion?: CSSMotionProps | ((placement: Placement) => CSSMotionProps);
2236
}
2337

24-
const NotificationList: React.FC<NotificationListProps> = () => {
25-
return null;
38+
const NotificationList: React.FC<NotificationListProps> = (props) => {
39+
const { configList = [], pauseOnHover, classNames, styles, maxCount, motion, placement } = props;
40+
41+
// ========================== Data ==========================
42+
const mergedConfigList =
43+
typeof maxCount === 'number' && maxCount > 0 ? configList.slice(-maxCount) : configList;
44+
45+
const keys = mergedConfigList.map((config) => ({
46+
config,
47+
key: String(config.key),
48+
}));
49+
50+
// ========================= Motion =========================
51+
const placementMotion = typeof motion === 'function' ? motion(placement) : motion;
52+
53+
// ========================= Render =========================
54+
return (
55+
<CSSMotionList component="div" keys={keys} motionAppear {...placementMotion}>
56+
{({ config, className, style }, nodeRef) => (
57+
<Notification
58+
{...config}
59+
ref={nodeRef}
60+
className={clsx(className, config.className)}
61+
style={{
62+
...style,
63+
...config.style,
64+
}}
65+
classNames={{
66+
root: clsx(classNames?.root, config.classNames?.root),
67+
close: clsx(classNames?.close, config.classNames?.close),
68+
}}
69+
styles={{
70+
root: {
71+
...styles?.root,
72+
...config.styles?.root,
73+
},
74+
close: {
75+
...styles?.close,
76+
...config.styles?.close,
77+
},
78+
}}
79+
pauseOnHover={config.pauseOnHover ?? pauseOnHover}
80+
/>
81+
)}
82+
</CSSMotionList>
83+
);
2684
};
2785

2886
export default NotificationList;

0 commit comments

Comments
 (0)