Skip to content

Commit f1d3053

Browse files
author
Bair Buldaev
committed
fix: change the naming and and the comment for requestAnimationFrame
1 parent eb93b6b commit f1d3053

5 files changed

Lines changed: 22 additions & 48 deletions

File tree

src/components/Notification/Notification.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import './Notification.scss';
1212
const b = block('notification');
1313

1414
type Props = {
15-
rootRef?: React.RefObject<HTMLDivElement>;
15+
wrapperRef?: React.RefObject<HTMLDivElement>;
1616
notification: NotificationProps;
1717
};
1818

@@ -26,7 +26,7 @@ export const Notification = React.memo(function Notification(props: Props) {
2626
const ref = React.useRef<HTMLDivElement>(null);
2727
const {t} = i18n.useTranslation();
2828
const mobile = useMobile();
29-
const {rootRef, notification} = props;
29+
const {wrapperRef, notification} = props;
3030
const {
3131
title,
3232
content,
@@ -66,7 +66,7 @@ export const Notification = React.memo(function Notification(props: Props) {
6666
if (typeof content === 'function') {
6767
renderedContent = (
6868
<div className={b('content-wrapper')}>
69-
<div className={b('content')}>{content({rootRef})}</div>
69+
<div className={b('content')}>{content({wrapperRef})}</div>
7070
</div>
7171
);
7272
} else {

src/components/Notification/NotificationWithSwipe.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const swipeActionContainerCls = b('swipe-action-container');
1717
type Props = {
1818
notification: NotificationProps;
1919
swipeThreshold?: number;
20-
rootRef?: React.RefObject<HTMLDivElement>;
20+
wrapperRef?: React.RefObject<HTMLDivElement>;
2121
};
2222

2323
export const NotificationWithSwipe = React.memo(function NotificationWithSwipe(props: Props) {
@@ -28,7 +28,7 @@ export const NotificationWithSwipe = React.memo(function NotificationWithSwipe(p
2828
}
2929

3030
const ref = React.useRef<HTMLDivElement>(null);
31-
const {notification, rootRef} = props;
31+
const {notification, wrapperRef} = props;
3232
const swipeActions = notification.swipeActions;
3333
const leftAction = swipeActions && 'left' in swipeActions ? swipeActions.left : undefined;
3434
const rightAction = swipeActions && 'right' in swipeActions ? swipeActions.right : undefined;
@@ -136,7 +136,7 @@ export const NotificationWithSwipe = React.memo(function NotificationWithSwipe(p
136136
>
137137
{leftAction ? renderAction(leftAction) : null}
138138
<div className={notificationWrapperCls}>
139-
<Notification notification={notification} rootRef={rootRef} />
139+
<Notification notification={notification} wrapperRef={wrapperRef} />
140140
</div>
141141
{rightAction ? renderAction(rightAction) : null}
142142
</div>

src/components/Notification/definitions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export type NotificationProps = {
2626
id: string;
2727
content:
2828
| React.ReactNode
29-
| ((props: {rootRef?: React.RefObject<HTMLDivElement>}) => React.ReactNode);
29+
| ((props: {wrapperRef?: React.RefObject<HTMLDivElement>}) => React.ReactNode);
3030

3131
title?: React.ReactNode;
3232
formattedDate?: React.ReactNode;

src/components/Notifications/NotificationWrapper.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ export const NotificationWrapper = (props: {
4444
element.style.maxHeight = `${element.scrollHeight}px`;
4545
element.style.transition = 'max-height 0.3s';
4646

47+
// Firefox batches style changes made within a single frame, so setting maxHeight
48+
// to scrollHeight and then to 0px in the same frame skips the transition entirely.
49+
// Two nested requestAnimationFrame calls guarantee the browser commits the initial
50+
// maxHeight in one frame before applying 0px in the next, so the animation runs.
4751
requestAnimationFrame(() => {
4852
requestAnimationFrame(() => {
4953
element.style.maxHeight = '0px';
@@ -78,10 +82,10 @@ export const NotificationWrapper = (props: {
7882
<NotificationWithSwipe
7983
notification={notification}
8084
swipeThreshold={swipeThreshold}
81-
rootRef={ref}
85+
wrapperRef={ref}
8286
/>
8387
) : (
84-
<Notification notification={notification} rootRef={ref} />
88+
<Notification notification={notification} wrapperRef={ref} />
8589
)}
8690
</div>
8791
</li>

src/components/Notifications/__stories__/mockData.tsx

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react';
22

33
import {Archive, ArrowRotateLeft, CircleCheck, Funnel, TrashBin} from '@gravity-ui/icons';
4-
import {Button, DropdownMenu, Flex, Icon, Link} from '@gravity-ui/uikit';
4+
import {Disclosure, DropdownMenu, Flex, Icon, Link} from '@gravity-ui/uikit';
55

66
import {NotificationAction} from '../../Notification/NotificationAction';
77
import {NotificationSwipeAction} from '../../Notification/NotificationSwipeAction';
@@ -89,54 +89,25 @@ export const notificationBottomActions: JSX.Element = (
8989
</React.Fragment>
9090
);
9191

92-
export const LongNotificationContent = (props: {
93-
rootRef?: React.RefObject<HTMLDivElement>;
94-
wrapperRef?: React.RefObject<HTMLDivElement>;
95-
}) => {
96-
const {rootRef} = props;
97-
const [expanded, setExpanded] = React.useState(false);
98-
const prevExpandedRef = React.useRef(false);
92+
export const LongNotificationContent = (props: {wrapperRef?: React.RefObject<HTMLDivElement>}) => {
93+
const {wrapperRef} = props;
9994

100-
React.useLayoutEffect(() => {
101-
if (prevExpandedRef.current && !expanded) {
95+
const handleUpdate = (expanded: boolean) => {
96+
if (!expanded) {
10297
requestAnimationFrame(() => {
103-
rootRef?.current?.scrollIntoView({block: 'nearest', behavior: 'smooth'});
98+
wrapperRef?.current?.scrollIntoView({block: 'nearest', behavior: 'smooth'});
10499
});
105100
}
106-
107-
prevExpandedRef.current = expanded;
108-
}, [expanded, rootRef]);
109-
110-
const handleExpand = (event: React.MouseEvent<HTMLButtonElement>) => {
111-
event.preventDefault();
112-
setExpanded(true);
113-
};
114-
115-
const handleCollapse = (event: React.MouseEvent<HTMLButtonElement>) => {
116-
event.preventDefault();
117-
setExpanded(false);
118101
};
119102

120-
if (expanded) {
121-
return (
103+
return (
104+
<Disclosure summary="Collapsed content" onUpdate={handleUpdate}>
122105
<Flex direction="column" gap={1}>
123106
{Array.from({length: 20}, (_, index) => (
124107
<i key={index}>{'Long expanded content. '}</i>
125108
))}
126-
<Button view="flat-secondary" onClick={handleCollapse}>
127-
Collapse
128-
</Button>
129109
</Flex>
130-
);
131-
}
132-
133-
return (
134-
<Flex direction="column" gap={1}>
135-
<span>Collapsed content</span>
136-
<Button view="flat-secondary" onClick={handleExpand}>
137-
Expand
138-
</Button>
139-
</Flex>
110+
</Disclosure>
140111
);
141112
};
142113

@@ -209,7 +180,6 @@ export const mockNotifications: NotificationProps[] = [
209180
content: (contentProps) => <LongNotificationContent {...contentProps} />,
210181
formattedDate: '29 seconds ago',
211182
swipeActions: notificationsMockSwipeActions,
212-
href: 'https://ya.ru',
213183
},
214184
{
215185
id: 'yandex',

0 commit comments

Comments
 (0)