|
1 | 1 | import { CSSMotionList } from '@rc-component/motion'; |
2 | 2 | import type { CSSMotionProps } from '@rc-component/motion'; |
3 | | -import { composeRef } from '@rc-component/util/lib/ref'; |
| 3 | +import { useComposeRef } from '@rc-component/util/lib/ref'; |
4 | 4 | import { clsx } from 'clsx'; |
5 | 5 | import * as React from 'react'; |
6 | 6 | import useListPosition from '../hooks/useListPosition'; |
@@ -40,6 +40,116 @@ export interface NotificationListProps { |
40 | 40 | onAllRemoved?: (placement: Placement) => void; |
41 | 41 | } |
42 | 42 |
|
| 43 | +interface NotificationListItemProps { |
| 44 | + config: NotificationListConfig; |
| 45 | + components?: ComponentsType; |
| 46 | + contextClassNames?: NotificationClassNames; |
| 47 | + classNames?: NotificationClassNames; |
| 48 | + styles?: NotificationStyles; |
| 49 | + motionClassName?: string; |
| 50 | + motionStyle?: React.CSSProperties; |
| 51 | + nodeRef: React.Ref<HTMLDivElement>; |
| 52 | + prefixCls: string; |
| 53 | + offset?: number; |
| 54 | + notificationIndex: number; |
| 55 | + stackInThreshold: boolean; |
| 56 | + listHovering: boolean; |
| 57 | + stackEnabled: boolean; |
| 58 | + pauseOnHover?: boolean; |
| 59 | + setNodeSize: (key: string, node: HTMLDivElement | null) => void; |
| 60 | + onNoticeClose?: (key: React.Key) => void; |
| 61 | +} |
| 62 | + |
| 63 | +const NotificationListItem: React.FC<NotificationListItemProps> = (props) => { |
| 64 | + const { |
| 65 | + config, |
| 66 | + components, |
| 67 | + contextClassNames, |
| 68 | + classNames, |
| 69 | + styles, |
| 70 | + motionClassName, |
| 71 | + motionStyle, |
| 72 | + nodeRef, |
| 73 | + prefixCls, |
| 74 | + offset, |
| 75 | + notificationIndex, |
| 76 | + stackInThreshold, |
| 77 | + listHovering, |
| 78 | + stackEnabled, |
| 79 | + pauseOnHover, |
| 80 | + setNodeSize, |
| 81 | + onNoticeClose, |
| 82 | + } = props; |
| 83 | + const { key, placement: itemPlacement, ...notificationConfig } = config; |
| 84 | + const strKey = String(key); |
| 85 | + |
| 86 | + const setItemRef = React.useCallback( |
| 87 | + (node: HTMLDivElement | null) => { |
| 88 | + setNodeSize(strKey, node); |
| 89 | + }, |
| 90 | + [setNodeSize, strKey], |
| 91 | + ); |
| 92 | + const ref = useComposeRef(nodeRef, setItemRef); |
| 93 | + |
| 94 | + return ( |
| 95 | + <Notification |
| 96 | + {...notificationConfig} |
| 97 | + ref={ref} |
| 98 | + prefixCls={prefixCls} |
| 99 | + offset={offset} |
| 100 | + notificationIndex={notificationIndex} |
| 101 | + stackInThreshold={stackInThreshold} |
| 102 | + className={clsx(contextClassNames?.notice, config.className)} |
| 103 | + style={config.style} |
| 104 | + classNames={{ |
| 105 | + wrapper: clsx(classNames?.wrapper, config.classNames?.wrapper), |
| 106 | + root: clsx(classNames?.root, config.classNames?.root, motionClassName), |
| 107 | + icon: clsx(classNames?.icon, config.classNames?.icon), |
| 108 | + section: clsx(classNames?.section, config.classNames?.section), |
| 109 | + close: clsx(classNames?.close, config.classNames?.close), |
| 110 | + progress: clsx(classNames?.progress, config.classNames?.progress), |
| 111 | + }} |
| 112 | + styles={{ |
| 113 | + wrapper: { |
| 114 | + ...styles?.wrapper, |
| 115 | + ...config.styles?.wrapper, |
| 116 | + }, |
| 117 | + root: { |
| 118 | + ...styles?.root, |
| 119 | + ...config.styles?.root, |
| 120 | + ...motionStyle, |
| 121 | + }, |
| 122 | + icon: { |
| 123 | + ...styles?.icon, |
| 124 | + ...config.styles?.icon, |
| 125 | + }, |
| 126 | + section: { |
| 127 | + ...styles?.section, |
| 128 | + ...config.styles?.section, |
| 129 | + }, |
| 130 | + close: { |
| 131 | + ...styles?.close, |
| 132 | + ...config.styles?.close, |
| 133 | + }, |
| 134 | + progress: { |
| 135 | + ...styles?.progress, |
| 136 | + ...config.styles?.progress, |
| 137 | + }, |
| 138 | + }} |
| 139 | + components={{ |
| 140 | + ...components, |
| 141 | + ...config.components, |
| 142 | + }} |
| 143 | + hovering={stackEnabled && listHovering} |
| 144 | + pauseOnHover={config.pauseOnHover ?? pauseOnHover} |
| 145 | + onClose={() => { |
| 146 | + config.onClose?.(); |
| 147 | + onNoticeClose?.(key); |
| 148 | + }} |
| 149 | + /> |
| 150 | + ); |
| 151 | +}; |
| 152 | + |
43 | 153 | const NotificationList: React.FC<NotificationListProps> = (props) => { |
44 | 154 | const { |
45 | 155 | configList = [], |
@@ -148,71 +258,31 @@ const NotificationList: React.FC<NotificationListProps> = (props) => { |
148 | 258 | }} |
149 | 259 | > |
150 | 260 | {({ config, className: motionClassName, style: motionStyle, index = 0 }, nodeRef) => { |
151 | | - const { key, placement: itemPlacement, ...notificationConfig } = config; |
| 261 | + const { key } = config; |
152 | 262 | const strKey = String(key); |
153 | 263 | const notificationIndex = keyList.length - index - 1; |
154 | 264 | const stackInThreshold = stackEnabled && notificationIndex < threshold; |
155 | 265 |
|
156 | | - const setItemRef = (node: HTMLDivElement | null) => { |
157 | | - setNodeSize(strKey, node); |
158 | | - }; |
159 | | - |
160 | 266 | return ( |
161 | | - <Notification |
| 267 | + <NotificationListItem |
162 | 268 | key={key} |
163 | | - {...notificationConfig} |
164 | | - ref={composeRef(nodeRef, setItemRef)} |
| 269 | + config={config} |
| 270 | + components={components} |
| 271 | + contextClassNames={contextClassNames} |
| 272 | + classNames={classNames} |
| 273 | + styles={styles} |
| 274 | + motionClassName={motionClassName} |
| 275 | + motionStyle={motionStyle} |
| 276 | + nodeRef={nodeRef} |
165 | 277 | prefixCls={prefixCls} |
166 | 278 | offset={notificationPosition.get(strKey)} |
167 | 279 | notificationIndex={notificationIndex} |
168 | 280 | stackInThreshold={stackInThreshold} |
169 | | - className={clsx(contextClassNames?.notice, config.className)} |
170 | | - style={config.style} |
171 | | - classNames={{ |
172 | | - wrapper: clsx(classNames?.wrapper, config.classNames?.wrapper), |
173 | | - root: clsx(classNames?.root, config.classNames?.root, motionClassName), |
174 | | - icon: clsx(classNames?.icon, config.classNames?.icon), |
175 | | - section: clsx(classNames?.section, config.classNames?.section), |
176 | | - close: clsx(classNames?.close, config.classNames?.close), |
177 | | - progress: clsx(classNames?.progress, config.classNames?.progress), |
178 | | - }} |
179 | | - styles={{ |
180 | | - wrapper: { |
181 | | - ...styles?.wrapper, |
182 | | - ...config.styles?.wrapper, |
183 | | - }, |
184 | | - root: { |
185 | | - ...styles?.root, |
186 | | - ...config.styles?.root, |
187 | | - ...motionStyle, |
188 | | - }, |
189 | | - icon: { |
190 | | - ...styles?.icon, |
191 | | - ...config.styles?.icon, |
192 | | - }, |
193 | | - section: { |
194 | | - ...styles?.section, |
195 | | - ...config.styles?.section, |
196 | | - }, |
197 | | - close: { |
198 | | - ...styles?.close, |
199 | | - ...config.styles?.close, |
200 | | - }, |
201 | | - progress: { |
202 | | - ...styles?.progress, |
203 | | - ...config.styles?.progress, |
204 | | - }, |
205 | | - }} |
206 | | - components={{ |
207 | | - ...components, |
208 | | - ...config.components, |
209 | | - }} |
210 | | - hovering={stackEnabled && listHovering} |
211 | | - pauseOnHover={config.pauseOnHover ?? pauseOnHover} |
212 | | - onClose={() => { |
213 | | - config.onClose?.(); |
214 | | - onNoticeClose?.(key); |
215 | | - }} |
| 281 | + listHovering={listHovering} |
| 282 | + stackEnabled={stackEnabled} |
| 283 | + pauseOnHover={pauseOnHover} |
| 284 | + setNodeSize={setNodeSize} |
| 285 | + onNoticeClose={onNoticeClose} |
216 | 286 | /> |
217 | 287 | ); |
218 | 288 | }} |
|
0 commit comments