Merge pull request #15899 from ant-design/affix-size

fix: Affix should dynamic adjust if size changed
This commit is contained in:
信鑫-King 2019-04-07 19:40:35 +08:00 committed by GitHub
commit 8199f4b9f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 10 deletions

View File

@ -53,7 +53,7 @@ class ReactResizeObserver extends React.Component<ResizeObserverProps, {}> {
}
render() {
const { children } = this.props;
const { children = null } = this.props;
return children;
}
}

View File

@ -137,4 +137,30 @@ describe('Affix Render', () => {
expect(wrapper.instance().state.affixStyle).toBe(undefined);
expect(wrapper.instance().state.placeholderStyle).toBe(undefined);
});
it('updatePosition when size changed', () => {
document.body.innerHTML = '<div id="mounter" />';
const updateCalled = jest.fn();
wrapper = mount(<AffixMounter offsetBottom={0} onTestUpdatePosition={updateCalled} />, {
attachTo: document.getElementById('mounter'),
});
jest.runAllTimers();
movePlaceholder(300);
expect(wrapper.instance().affix.state.affixStyle).toBeTruthy();
jest.runAllTimers();
wrapper.update();
// Mock trigger resize
updateCalled.mockReset();
wrapper
.find('ReactResizeObserver')
.instance()
.onResize();
jest.runAllTimers();
expect(updateCalled).toHaveBeenCalled();
});
});

View File

@ -4,6 +4,7 @@ import classNames from 'classnames';
import omit from 'omit.js';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame';
import ResizeObserver from '../_util/resizeObserver';
import warning from '../_util/warning';
import { addObserveTarget, removeObserveTarget, getTargetRect } from './utils';
@ -109,13 +110,21 @@ class Affix extends React.Component<AffixProps, AffixState> {
// Handle realign logic
@throttleByAnimationFrameDecorator()
// @ts-ignore TS6133
updatePosition(e: Event) {
updatePosition(e?: Event) {
// event param is used before. Keep compatible ts define here.
this.setState({
status: AffixStatus.Prepare,
affixStyle: undefined,
placeholderStyle: undefined,
});
// Test if `updatePosition` called
if (process.env.NODE_ENV === 'test') {
const { onTestUpdatePosition } = this.props as any;
if (onTestUpdatePosition) {
onTestUpdatePosition();
}
}
}
measure = () => {
@ -194,13 +203,11 @@ class Affix extends React.Component<AffixProps, AffixState> {
[getPrefixCls('affix', prefixCls)]: affixStyle,
});
const props = omit(this.props, [
'prefixCls',
'offsetTop',
'offsetBottom',
'target',
'onChange',
]);
let props = omit(this.props, ['prefixCls', 'offsetTop', 'offsetBottom', 'target', 'onChange']);
// Omit this since `onTestUpdatePosition` only works on test.
if (process.env.NODE_ENV === 'test') {
props = omit(props, ['onTestUpdatePosition']);
}
const mergedPlaceholderStyle = {
...(status === AffixStatus.None ? placeholderStyle : null),
...style,
@ -208,7 +215,7 @@ class Affix extends React.Component<AffixProps, AffixState> {
return (
<div {...props} style={mergedPlaceholderStyle} ref={this.savePlaceholderNode}>
<div className={className} ref={this.saveFixedNode} style={this.state.affixStyle}>
{children}
<ResizeObserver onResize={this.updatePosition}>{children}</ResizeObserver>
</div>
</div>
);