Skip to content

Commit 91f176f

Browse files
zombieJclaude
andcommitted
refactor: move reverse logic to useListPosition hook
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 73553de commit 91f176f

3 files changed

Lines changed: 28 additions & 20 deletions

File tree

src/NotificationList.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,18 @@ const NotificationList: React.FC<NotificationListProps> = (props) => {
6363
const { classNames: contextClassNames } = React.useContext(NotificationContext);
6464

6565
// ========================== Data ==========================
66-
const mergedConfigList = React.useMemo(() => configList.slice().reverse(), [configList]);
67-
6866
const keys = React.useMemo(
6967
() =>
70-
mergedConfigList.map((config) => ({
68+
configList.map((config) => ({
7169
config,
7270
key: String(config.key),
7371
})),
74-
[mergedConfigList],
72+
[configList],
73+
);
74+
const keyList = React.useMemo(
75+
() => configList.map((config) => String(config.key)).reverse(),
76+
[configList],
7577
);
76-
const keyList = React.useMemo(() => keys.map(({ key }) => key), [keys]);
7778

7879
// ========================= Motion =========================
7980
const placementMotion = typeof motion === 'function' ? motion(placement) : motion;
@@ -91,7 +92,7 @@ const NotificationList: React.FC<NotificationListProps> = (props) => {
9192
};
9293
}, [expanded, offset, stackEnabled, threshold]);
9394

94-
const [notificationPosition, setNodeSize] = useListPosition(mergedConfigList, stackPosition);
95+
const [notificationPosition, setNodeSize] = useListPosition(configList, stackPosition);
9596
const { contentRef, onWheel, scrollOffset, viewportRef } = useListScroll(
9697
keyList,
9798
notificationPosition,
@@ -145,7 +146,7 @@ const NotificationList: React.FC<NotificationListProps> = (props) => {
145146
}}
146147
>
147148
{({ config, className: motionClassName, style: motionStyle }, nodeRef) => {
148-
const { key, placement: itemPlacement, ...notificationConfig } = config;
149+
const { key, placement: _placement, ...notificationConfig } = config;
149150
const strKey = String(key);
150151

151152
return (

src/hooks/useListPosition/index.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,19 @@ export default function useListPosition(configList: { key: React.Key }[], stack?
1414
let offsetY = 0;
1515
const nextNotificationPosition = new Map<string, NodePosition>();
1616

17-
configList.forEach((config) => {
18-
const key = String(config.key);
19-
const nodePosition = {
20-
x: 0,
21-
y: offsetY,
22-
};
17+
configList
18+
.slice()
19+
.reverse()
20+
.forEach((config) => {
21+
const key = String(config.key);
22+
const nodePosition = {
23+
x: 0,
24+
y: offsetY,
25+
};
2326

24-
nextNotificationPosition.set(key, nodePosition);
25-
// offsetY += (sizeMap[key]?.height ?? 0) + (stack?.offset ?? 0);
26-
offsetY += (stack ? stack.offset : sizeMap[key]?.height) ?? 0;
27-
});
27+
nextNotificationPosition.set(key, nodePosition);
28+
offsetY += (stack ? stack.offset : sizeMap[key]?.height) ?? 0;
29+
});
2830

2931
return nextNotificationPosition;
3032
}, [configList, sizeMap, stack]);

tests/stack.test.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ describe('stack', () => {
8787

8888
it('passes stack offset to list position when collapsed', () => {
8989
const Demo = () => {
90+
const countRef = React.useRef(0);
9091
const [api, holder] = useNotification({
9192
stack: { threshold: 1, offset: 12 },
9293
});
@@ -96,8 +97,11 @@ describe('stack', () => {
9697
<button
9798
type="button"
9899
onClick={() => {
100+
const index = countRef.current;
101+
countRef.current += 1;
102+
99103
api.open({
100-
content: <div className="context-content">Test</div>,
104+
content: <div className={`context-content-${index}`}>Test {index}</div>,
101105
duration: false,
102106
});
103107
}}
@@ -116,8 +120,9 @@ describe('stack', () => {
116120
const notices = Array.from(document.querySelectorAll<HTMLElement>('.rc-notification-notice'));
117121
const offsetList = notices.map((notice) => notice.style.getPropertyValue('--notification-y'));
118122

119-
expect(offsetList).toContain('0px');
120-
expect(offsetList).toContain('12px');
123+
expect(notices[0].querySelector('.context-content-0')).toBeTruthy();
124+
expect(notices[1].querySelector('.context-content-1')).toBeTruthy();
125+
expect(offsetList).toEqual(['12px', '0px']);
121126

122127
fireEvent.mouseEnter(document.querySelector('.rc-notification-list'));
123128

0 commit comments

Comments
 (0)