mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 09:26:06 +08:00
chore: remove throttleByAnimationFrameDecorator (#38693)
* chore: remove throttleByAnimationFrameDecorator * fix * fix
This commit is contained in:
parent
cd52a3dce0
commit
52cb37f487
@ -6,10 +6,7 @@ import { waitFakeTimer, render, fireEvent } from '../../../tests/utils';
|
|||||||
import getDataOrAriaProps from '../getDataOrAriaProps';
|
import getDataOrAriaProps from '../getDataOrAriaProps';
|
||||||
import delayRaf from '../raf';
|
import delayRaf from '../raf';
|
||||||
import { isStyleSupport } from '../styleChecker';
|
import { isStyleSupport } from '../styleChecker';
|
||||||
import {
|
import throttleByAnimationFrame from '../throttleByAnimationFrame';
|
||||||
throttleByAnimationFrame,
|
|
||||||
throttleByAnimationFrameDecorator,
|
|
||||||
} from '../throttleByAnimationFrame';
|
|
||||||
import TransButton from '../transButton';
|
import TransButton from '../transButton';
|
||||||
|
|
||||||
describe('Test utils function', () => {
|
describe('Test utils function', () => {
|
||||||
@ -49,22 +46,6 @@ describe('Test utils function', () => {
|
|||||||
|
|
||||||
expect(callback).not.toHaveBeenCalled();
|
expect(callback).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throttleByAnimationFrameDecorator should works', async () => {
|
|
||||||
const callbackFn = jest.fn();
|
|
||||||
class Test {
|
|
||||||
@throttleByAnimationFrameDecorator()
|
|
||||||
callback() {
|
|
||||||
callbackFn();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const test = new Test();
|
|
||||||
test.callback();
|
|
||||||
test.callback();
|
|
||||||
test.callback();
|
|
||||||
await waitFakeTimer();
|
|
||||||
expect(callbackFn).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getDataOrAriaProps', () => {
|
describe('getDataOrAriaProps', () => {
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
import raf from 'rc-util/lib/raf';
|
import raf from 'rc-util/lib/raf';
|
||||||
|
|
||||||
export function throttleByAnimationFrame<T extends unknown[]>(fn: (...args: T) => void) {
|
type throttledFn = (...args: any[]) => void;
|
||||||
|
|
||||||
|
type throttledCancelFn = { cancel: () => void };
|
||||||
|
|
||||||
|
function throttleByAnimationFrame<T extends any[]>(fn: (...args: T) => void) {
|
||||||
let requestId: number | null;
|
let requestId: number | null;
|
||||||
|
|
||||||
const later = (args: T) => () => {
|
const later = (args: T) => () => {
|
||||||
@ -8,10 +12,7 @@ export function throttleByAnimationFrame<T extends unknown[]>(fn: (...args: T) =
|
|||||||
fn(...args);
|
fn(...args);
|
||||||
};
|
};
|
||||||
|
|
||||||
const throttled: {
|
const throttled: throttledFn & throttledCancelFn = (...args: T) => {
|
||||||
(...args: T): void;
|
|
||||||
cancel: () => void;
|
|
||||||
} = (...args: T) => {
|
|
||||||
if (requestId == null) {
|
if (requestId == null) {
|
||||||
requestId = raf(later(args));
|
requestId = raf(later(args));
|
||||||
}
|
}
|
||||||
@ -25,32 +26,4 @@ export function throttleByAnimationFrame<T extends unknown[]>(fn: (...args: T) =
|
|||||||
return throttled;
|
return throttled;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function throttleByAnimationFrameDecorator() {
|
export default throttleByAnimationFrame;
|
||||||
return function throttle(target: any, key: string, descriptor: any) {
|
|
||||||
const fn = descriptor.value;
|
|
||||||
let definingProperty = false;
|
|
||||||
return {
|
|
||||||
configurable: true,
|
|
||||||
get() {
|
|
||||||
// In IE11 calling Object.defineProperty has a side-effect of evaluating the
|
|
||||||
// getter for the property which is being replaced. This causes infinite
|
|
||||||
// recursion and an "Out of stack space" error.
|
|
||||||
// eslint-disable-next-line no-prototype-builtins
|
|
||||||
if (definingProperty || this === target.prototype || this.hasOwnProperty(key)) {
|
|
||||||
/* istanbul ignore next */
|
|
||||||
return fn;
|
|
||||||
}
|
|
||||||
|
|
||||||
const boundFn = throttleByAnimationFrame(fn.bind(this));
|
|
||||||
definingProperty = true;
|
|
||||||
Object.defineProperty(this, key, {
|
|
||||||
value: boundFn,
|
|
||||||
configurable: true,
|
|
||||||
writable: true,
|
|
||||||
});
|
|
||||||
definingProperty = false;
|
|
||||||
return boundFn;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@ -4,7 +4,7 @@ import omit from 'rc-util/lib/omit';
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import type { ConfigConsumerProps } from '../config-provider';
|
import type { ConfigConsumerProps } from '../config-provider';
|
||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame';
|
import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
|
||||||
|
|
||||||
import useStyle from './style';
|
import useStyle from './style';
|
||||||
import {
|
import {
|
||||||
@ -126,9 +126,9 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
|||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
removeObserveTarget(this);
|
removeObserveTarget(this);
|
||||||
(this.updatePosition as any).cancel();
|
this.updatePosition.cancel();
|
||||||
// https://github.com/ant-design/ant-design/issues/22683
|
// https://github.com/ant-design/ant-design/issues/22683
|
||||||
(this.lazyUpdatePosition as any).cancel();
|
this.lazyUpdatePosition.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
getOffsetTop = () => {
|
getOffsetTop = () => {
|
||||||
@ -228,14 +228,11 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle realign logic
|
updatePosition = throttleByAnimationFrame(() => {
|
||||||
@throttleByAnimationFrameDecorator()
|
|
||||||
updatePosition() {
|
|
||||||
this.prepareMeasure();
|
this.prepareMeasure();
|
||||||
}
|
});
|
||||||
|
|
||||||
@throttleByAnimationFrameDecorator()
|
lazyUpdatePosition = throttleByAnimationFrame(() => {
|
||||||
lazyUpdatePosition() {
|
|
||||||
const targetFunc = this.getTargetFunc();
|
const targetFunc = this.getTargetFunc();
|
||||||
const { affixStyle } = this.state;
|
const { affixStyle } = this.state;
|
||||||
|
|
||||||
@ -262,7 +259,7 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
|||||||
|
|
||||||
// Directly call prepare measure since it's already throttled.
|
// Directly call prepare measure since it's already throttled.
|
||||||
this.prepareMeasure();
|
this.prepareMeasure();
|
||||||
}
|
});
|
||||||
|
|
||||||
// =================== Render ===================
|
// =================== Render ===================
|
||||||
render() {
|
render() {
|
||||||
@ -288,21 +285,11 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ResizeObserver
|
<ResizeObserver onResize={this.updatePosition}>
|
||||||
onResize={() => {
|
|
||||||
this.updatePosition();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div {...props} ref={this.savePlaceholderNode}>
|
<div {...props} ref={this.savePlaceholderNode}>
|
||||||
{affixStyle && <div style={placeholderStyle} aria-hidden="true" />}
|
{affixStyle && <div style={placeholderStyle} aria-hidden="true" />}
|
||||||
<div className={className} ref={this.saveFixedNode} style={affixStyle}>
|
<div className={className} ref={this.saveFixedNode} style={affixStyle}>
|
||||||
<ResizeObserver
|
<ResizeObserver onResize={this.updatePosition}>{children}</ResizeObserver>
|
||||||
onResize={() => {
|
|
||||||
this.updatePosition();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</ResizeObserver>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ResizeObserver>
|
</ResizeObserver>
|
||||||
@ -321,7 +308,6 @@ const AffixFC = React.forwardRef<Affix, AffixProps>((props, ref) => {
|
|||||||
|
|
||||||
const AffixProps: InternalAffixProps = {
|
const AffixProps: InternalAffixProps = {
|
||||||
...props,
|
...props,
|
||||||
|
|
||||||
affixPrefixCls,
|
affixPrefixCls,
|
||||||
rootClassName: hashId,
|
rootClassName: hashId,
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@ import { ConfigContext } from '../config-provider';
|
|||||||
import getScroll from '../_util/getScroll';
|
import getScroll from '../_util/getScroll';
|
||||||
import { cloneElement } from '../_util/reactNode';
|
import { cloneElement } from '../_util/reactNode';
|
||||||
import scrollTo from '../_util/scrollTo';
|
import scrollTo from '../_util/scrollTo';
|
||||||
import { throttleByAnimationFrame } from '../_util/throttleByAnimationFrame';
|
import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
|
||||||
import warning from '../_util/warning';
|
import warning from '../_util/warning';
|
||||||
import useStyle from './style';
|
import useStyle from './style';
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ interface ChildrenProps {
|
|||||||
visible?: boolean; // Only for test. Don't use it.
|
visible?: boolean; // Only for test. Don't use it.
|
||||||
}
|
}
|
||||||
|
|
||||||
const BackTopContent: React.FC<ChildrenProps> = props => {
|
const BackTopContent: React.FC<ChildrenProps> = (props) => {
|
||||||
const { prefixCls, rootPrefixCls, children, visible } = props;
|
const { prefixCls, rootPrefixCls, children, visible } = props;
|
||||||
const defaultElement = (
|
const defaultElement = (
|
||||||
<div className={`${prefixCls}-content`}>
|
<div className={`${prefixCls}-content`}>
|
||||||
@ -52,7 +52,7 @@ const BackTopContent: React.FC<ChildrenProps> = props => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const BackTop: React.FC<BackTopProps> = props => {
|
const BackTop: React.FC<BackTopProps> = (props) => {
|
||||||
const [visible, setVisible] = useMergedState(false, {
|
const [visible, setVisible] = useMergedState(false, {
|
||||||
value: props.visible,
|
value: props.visible,
|
||||||
});
|
});
|
||||||
|
@ -9,12 +9,12 @@ import type { ConfigConsumerProps } from '../config-provider';
|
|||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import getScroll from '../_util/getScroll';
|
import getScroll from '../_util/getScroll';
|
||||||
import scrollTo from '../_util/scrollTo';
|
import scrollTo from '../_util/scrollTo';
|
||||||
import { throttleByAnimationFrame } from '../_util/throttleByAnimationFrame';
|
import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
|
||||||
import FloatButtonGroupContext from './context';
|
import FloatButtonGroupContext from './context';
|
||||||
import type { BackTopProps, FloatButtonShape } from './interface';
|
import type { BackTopProps, FloatButtonShape } from './interface';
|
||||||
import useStyle from './style';
|
import useStyle from './style';
|
||||||
|
|
||||||
const BackTop: React.FC<BackTopProps> = props => {
|
const BackTop: React.FC<BackTopProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
className = '',
|
className = '',
|
||||||
@ -63,7 +63,7 @@ const BackTop: React.FC<BackTopProps> = props => {
|
|||||||
};
|
};
|
||||||
}, [target]);
|
}, [target]);
|
||||||
|
|
||||||
const scrollToTop: React.MouseEventHandler<HTMLDivElement> = e => {
|
const scrollToTop: React.MouseEventHandler<HTMLDivElement> = (e) => {
|
||||||
scrollTo(0, { getContainer: target || getDefaultTarget, duration });
|
scrollTo(0, { getContainer: target || getDefaultTarget, duration });
|
||||||
if (typeof onClick === 'function') {
|
if (typeof onClick === 'function') {
|
||||||
onClick(e);
|
onClick(e);
|
||||||
|
Loading…
Reference in New Issue
Block a user