Skip to content

Commit a4337a4

Browse files
authored
feat: add scrollBehavior option to Channel (#676)
Addresses one of request in https://sendbird.atlassian.net/browse/AC-12 Added [`scrollBehavior`](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior) prop to allow user to pass `"smooth"` option on scroll event via Channel component(provider). But I set the default option to `auto` which is an initial value of this CSS property not to change the existing behavior.
1 parent cf3c084 commit a4337a4

File tree

6 files changed

+60
-0
lines changed

6 files changed

+60
-0
lines changed

src/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,7 @@ type ChannelContextProps = {
743743
renderUserProfile?: (props: RenderUserProfileProps) => React.ReactElement;
744744
disableUserProfile?: boolean;
745745
disableMarkAsRead?: boolean;
746+
scrollBehavior?: 'smooth' | 'auto';
746747
};
747748

748749
interface ChannelUIProps {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { renderHook } from '@testing-library/react';
2+
import { useScrollBehavior } from '../useScrollBehavior';
3+
import { useChannelContext } from '../../../../context/ChannelProvider';
4+
5+
jest.mock('../../../../context/ChannelProvider', () => ({
6+
useChannelContext: jest.fn(),
7+
}));
8+
9+
describe('useScrollBehavior', () => {
10+
it('should set scroll behavior on scrollRef', () => {
11+
const scrollRefMock = { current: { style: { scrollBehavior: 'auto' } } };
12+
const scrollBehaviorMock = 'smooth';
13+
14+
useChannelContext.mockReturnValue({
15+
scrollRef: scrollRefMock,
16+
scrollBehavior: scrollBehaviorMock,
17+
});
18+
19+
renderHook(() => useScrollBehavior());
20+
21+
expect(scrollRefMock.current.style.scrollBehavior).toBe(scrollBehaviorMock);
22+
});
23+
24+
it('should set the scrollBehavior to `auto` by default if scrollBehavior prop is not set', () => {
25+
const scrollRefMock = { current: { style: { } } };
26+
27+
useChannelContext.mockReturnValue({
28+
scrollRef: scrollRefMock,
29+
});
30+
31+
renderHook(() => useScrollBehavior());
32+
33+
expect(scrollRefMock.current.style.scrollBehavior).toBe('auto');
34+
});
35+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { useEffect } from 'react';
2+
import { useChannelContext } from '../../../context/ChannelProvider';
3+
4+
export function useScrollBehavior() {
5+
const {
6+
scrollRef,
7+
scrollBehavior = 'auto',
8+
} = useChannelContext();
9+
10+
useEffect(() => {
11+
if (scrollRef.current) {
12+
scrollRef.current.style.scrollBehavior = scrollBehavior;
13+
}
14+
}, [scrollRef.current]);
15+
16+
return null;
17+
}

src/modules/Channel/components/MessageList/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { UserMessage } from '@sendbird/chat/message';
1717
import { MessageProvider } from '../../../Message/context/MessageProvider';
1818
import { useHandleOnScrollCallback } from '../../../../hooks/useHandleOnScrollCallback';
1919
import { useSetScrollToBottom } from './hooks/useSetScrollToBottom';
20+
import { useScrollBehavior } from './hooks/useScrollBehavior';
2021

2122
const SCROLL_BOTTOM_PADDING = 50;
2223

@@ -61,6 +62,8 @@ const MessageList: React.FC<MessageListProps> = ({
6162
: allMessages;
6263
const markAsReadScheduler = store.config.markAsReadScheduler;
6364

65+
useScrollBehavior();
66+
6467
const onScroll = () => {
6568
const element = scrollRef?.current;
6669
if (element == null) {

src/modules/Channel/context/ChannelProvider.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ export type ChannelContextProps = {
9595
onQuoteMessageClick?: (props: { message: UserMessage | FileMessage }) => void;
9696
onMessageAnimated?: () => void;
9797
onMessageHighlighted?: () => void;
98+
scrollBehavior?: 'smooth' | 'auto';
9899
};
99100

100101
interface MessageStoreInterface {
@@ -186,6 +187,7 @@ const ChannelProvider: React.FC<ChannelContextProps> = (props: ChannelContextPro
186187
onQuoteMessageClick,
187188
onMessageAnimated,
188189
onMessageHighlighted,
190+
scrollBehavior = 'auto',
189191
} = props;
190192

191193
const globalStore = useSendbirdStateContext();
@@ -483,6 +485,7 @@ const ChannelProvider: React.FC<ChannelContextProps> = (props: ChannelContextPro
483485
onScrollCallback,
484486
onScrollDownCallback,
485487
scrollRef,
488+
scrollBehavior,
486489
toggleReaction,
487490
}}>
488491
<UserProfileProvider

src/modules/Channel/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const Channel: React.FC<ChannelProps> = (props: ChannelProps) => {
3636
onQuoteMessageClick={props?.onQuoteMessageClick}
3737
onMessageAnimated={props?.onMessageAnimated}
3838
onMessageHighlighted={props?.onMessageHighlighted}
39+
scrollBehavior={props.scrollBehavior}
3940
>
4041
<ChannelUI
4142
isLoading={props?.isLoading}

0 commit comments

Comments
 (0)