Skip to content

Commit

Permalink
feat: add onScroll event handling for Mentions dropdown (#282)
Browse files Browse the repository at this point in the history
* feat: add onScroll event handling for Mentions dropdown

* docs: update MentionsProps interface documentation

* refactor: reorganize comments

* refactor: rename onDropdownScroll to onPopupScroll

* refactor: scroll handler and simplify props
  • Loading branch information
OysterD3 authored Dec 2, 2024
1 parent 273ee3c commit 0377044
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 1 deletion.
4 changes: 4 additions & 0 deletions docs/demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,7 @@ Option has `key` and filter only hit by `key`
## Allow Clear

<code src="./examples/allowClear.tsx"></code>

## On Scroll

<code src="./examples/onScroll.tsx"></code>
3 changes: 3 additions & 0 deletions docs/examples/debug.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export default () => (
<Mentions
rows={3}
defaultValue="Hello @ World @"
onScroll={e => {
console.log(e);
}}
open
options={[
{
Expand Down
4 changes: 4 additions & 0 deletions docs/examples/onScroll.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.on-scroll .rc-mentions-dropdown-menu {
max-height: 250px;
overflow: auto;
}
18 changes: 18 additions & 0 deletions docs/examples/onScroll.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import Mentions from 'rc-mentions';
import '../../assets/index.less';
import './onScroll.less';

export default () => (
<Mentions
rows={3}
defaultValue="Hello @ World @"
onPopupScroll={console.log}
dropdownClassName="on-scroll"
open
options={Array.from({ length: 1000 }).map((_, index) => ({
value: `item-${index}`,
label: `item-${index}`,
}))}
/>
);
2 changes: 2 additions & 0 deletions src/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function DropdownMenu(props: DropdownMenuProps) {
selectOption,
onFocus,
onBlur,
onScroll,
} = React.useContext(MentionsContext);

const { prefixCls, options } = props;
Expand All @@ -34,6 +35,7 @@ function DropdownMenu(props: DropdownMenuProps) {
}}
onFocus={onFocus}
onBlur={onBlur}
onScroll={onScroll}
>
{options.map((option, index) => {
const { key, disabled, className, style, label } = option;
Expand Down
13 changes: 12 additions & 1 deletion src/Mentions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export interface MentionsProps extends BaseTextareaAttrs {
classNames?: CommonInputProps['classNames'] & {
mentions?: string;
};
onPopupScroll?: (event: React.UIEvent<HTMLDivElement>) => void;
}

export interface MentionsRef {
Expand Down Expand Up @@ -130,6 +131,8 @@ const InternalMentions = forwardRef<MentionsRef, MentionsProps>(
// https://github.com/ant-design/ant-design/blob/df933e94efc8f376003bbdc658d64b64a0e53495/components/mentions/demo/render-panel.tsx
// @ts-expect-error
visible,
onPopupScroll,

// Rest
...restProps
} = props;
Expand Down Expand Up @@ -397,7 +400,6 @@ const InternalMentions = forwardRef<MentionsRef, MentionsProps>(
key === 'Shift' ||
which === KeyCode.ALT ||
key === 'AltGraph' ||

mergedMeasuring ||
(nextMeasureText !== mergedMeasureText && matchOption)
) {
Expand Down Expand Up @@ -455,7 +457,15 @@ const InternalMentions = forwardRef<MentionsRef, MentionsProps>(
onInternalBlur();
};

// ============================== Scroll ===============================
const onInternalPopupScroll: React.UIEventHandler<
HTMLDivElement
> = event => {
onPopupScroll?.(event);
};

// ============================== Render ==============================

return (
<div
className={classNames(prefixCls, className)}
Expand Down Expand Up @@ -485,6 +495,7 @@ const InternalMentions = forwardRef<MentionsRef, MentionsProps>(
selectOption,
onFocus: onDropdownFocus,
onBlur: onDropdownBlur,
onScroll: onInternalPopupScroll,
}}
>
<KeywordTrigger
Expand Down
1 change: 1 addition & 0 deletions src/MentionsContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface MentionsContextProps {
selectOption: (option: OptionProps) => void;
onFocus: React.FocusEventHandler<HTMLElement>;
onBlur: React.FocusEventHandler<HTMLElement>;
onScroll: React.UIEventHandler<HTMLElement>;
}

// We will never use default, here only to fix TypeScript warning
Expand Down
11 changes: 11 additions & 0 deletions tests/Mentions.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,17 @@ describe('Mentions', () => {
expect(container.firstChild).toHaveClass('rc-mentions-disabled');
});

it('onPopupScroll should work', () => {
const onPopupScroll = jest.fn();
const { container, baseElement } = renderMentions({ onPopupScroll });
simulateInput(container, '@');
act(() => {
jest.runAllTimers();
});
fireEvent.scroll(baseElement.querySelector('.rc-mentions-dropdown-menu'));
expect(onPopupScroll).toHaveBeenCalled();
});

describe('nativeElement', () => {
it('work', () => {
const ref = createRef<MentionsRef>();
Expand Down

0 comments on commit 0377044

Please sign in to comment.