diff --git a/docs/demo.md b/docs/demo.md index db616de..d6b87af 100644 --- a/docs/demo.md +++ b/docs/demo.md @@ -40,3 +40,7 @@ Option has `key` and filter only hit by `key` ## Allow Clear + +## On Scroll + + diff --git a/docs/examples/debug.tsx b/docs/examples/debug.tsx index 39f2ce8..7f7cfdd 100644 --- a/docs/examples/debug.tsx +++ b/docs/examples/debug.tsx @@ -6,6 +6,9 @@ export default () => ( { + console.log(e); + }} open options={[ { diff --git a/docs/examples/onScroll.less b/docs/examples/onScroll.less new file mode 100644 index 0000000..bd462a9 --- /dev/null +++ b/docs/examples/onScroll.less @@ -0,0 +1,4 @@ +.on-scroll .rc-mentions-dropdown-menu { + max-height: 250px; + overflow: auto; +} diff --git a/docs/examples/onScroll.tsx b/docs/examples/onScroll.tsx new file mode 100644 index 0000000..21c6da2 --- /dev/null +++ b/docs/examples/onScroll.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import Mentions from 'rc-mentions'; +import '../../assets/index.less'; +import './onScroll.less'; + +export default () => ( + ({ + value: `item-${index}`, + label: `item-${index}`, + }))} + /> +); diff --git a/src/DropdownMenu.tsx b/src/DropdownMenu.tsx index 637070d..59b5ca3 100644 --- a/src/DropdownMenu.tsx +++ b/src/DropdownMenu.tsx @@ -19,6 +19,7 @@ function DropdownMenu(props: DropdownMenuProps) { selectOption, onFocus, onBlur, + onScroll, } = React.useContext(MentionsContext); const { prefixCls, options } = props; @@ -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; diff --git a/src/Mentions.tsx b/src/Mentions.tsx index 668b535..0dd6a48 100644 --- a/src/Mentions.tsx +++ b/src/Mentions.tsx @@ -72,6 +72,7 @@ export interface MentionsProps extends BaseTextareaAttrs { classNames?: CommonInputProps['classNames'] & { mentions?: string; }; + onPopupScroll?: (event: React.UIEvent) => void; } export interface MentionsRef { @@ -130,6 +131,8 @@ const InternalMentions = forwardRef( // https://github.com/ant-design/ant-design/blob/df933e94efc8f376003bbdc658d64b64a0e53495/components/mentions/demo/render-panel.tsx // @ts-expect-error visible, + onPopupScroll, + // Rest ...restProps } = props; @@ -397,7 +400,6 @@ const InternalMentions = forwardRef( key === 'Shift' || which === KeyCode.ALT || key === 'AltGraph' || - mergedMeasuring || (nextMeasureText !== mergedMeasureText && matchOption) ) { @@ -455,7 +457,15 @@ const InternalMentions = forwardRef( onInternalBlur(); }; + // ============================== Scroll =============================== + const onInternalPopupScroll: React.UIEventHandler< + HTMLDivElement + > = event => { + onPopupScroll?.(event); + }; + // ============================== Render ============================== + return (
( selectOption, onFocus: onDropdownFocus, onBlur: onDropdownBlur, + onScroll: onInternalPopupScroll, }} > void; onFocus: React.FocusEventHandler; onBlur: React.FocusEventHandler; + onScroll: React.UIEventHandler; } // We will never use default, here only to fix TypeScript warning diff --git a/tests/Mentions.spec.tsx b/tests/Mentions.spec.tsx index 939ea6d..2c60d60 100644 --- a/tests/Mentions.spec.tsx +++ b/tests/Mentions.spec.tsx @@ -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();