mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-11 03:22:59 +08:00
fix: ⬆️ BackTop not working in iframe (#22788)
* docs: 🎬 improve BackTop demo * fix Backtop not working in iframe * fix lint * fix ci * fix ci * ✅ add more test case * ✅ add more test cases * fix ci
This commit is contained in:
parent
a91506cb6b
commit
aca2656721
11
components/_util/__tests__/getScroll.test.js
Normal file
11
components/_util/__tests__/getScroll.test.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment node
|
||||||
|
*/
|
||||||
|
import getScroll from '../getScroll';
|
||||||
|
|
||||||
|
describe('getScroll', () => {
|
||||||
|
it('getScroll return 0 in node envioronment', async () => {
|
||||||
|
expect(getScroll(null, true)).toBe(0);
|
||||||
|
expect(getScroll(null, false)).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
@ -1,17 +1,27 @@
|
|||||||
export default function getScroll(target: HTMLElement | Window | null, top: boolean): number {
|
export function isWindow(obj: any) {
|
||||||
|
return obj !== null && obj !== undefined && obj === obj.window;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function getScroll(
|
||||||
|
target: HTMLElement | Window | Document | null,
|
||||||
|
top: boolean,
|
||||||
|
): number {
|
||||||
if (typeof window === 'undefined') {
|
if (typeof window === 'undefined') {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prop = top ? 'pageYOffset' : 'pageXOffset';
|
|
||||||
const method = top ? 'scrollTop' : 'scrollLeft';
|
const method = top ? 'scrollTop' : 'scrollLeft';
|
||||||
const isWindow = target === window;
|
let result = 0;
|
||||||
|
if (isWindow(target)) {
|
||||||
let ret = isWindow ? (target as Window)[prop] : (target as HTMLElement)[method];
|
result = (target as Window)[top ? 'pageYOffset' : 'pageXOffset'];
|
||||||
// ie6,7,8 standard mode
|
} else if (target instanceof Document) {
|
||||||
if (isWindow && typeof ret !== 'number') {
|
result = target.documentElement[method];
|
||||||
ret = (document.documentElement as HTMLElement)[method];
|
} else if (target) {
|
||||||
|
result = (target as HTMLElement)[method];
|
||||||
}
|
}
|
||||||
|
if (target && !isWindow(target) && typeof result !== 'number') {
|
||||||
return ret;
|
result = ((target as HTMLElement).ownerDocument || (target as Document)).documentElement[
|
||||||
|
method
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import raf from 'raf';
|
import raf from 'raf';
|
||||||
import getScroll from './getScroll';
|
import getScroll, { isWindow } from './getScroll';
|
||||||
import { easeInOutCubic } from './easings';
|
import { easeInOutCubic } from './easings';
|
||||||
|
|
||||||
interface ScrollToOptions {
|
interface ScrollToOptions {
|
||||||
/** Scroll container, default as window */
|
/** Scroll container, default as window */
|
||||||
getContainer?: () => HTMLElement | Window;
|
getContainer?: () => HTMLElement | Window | Document;
|
||||||
/** Scroll end callback */
|
/** Scroll end callback */
|
||||||
callback?: () => any;
|
callback?: () => any;
|
||||||
/** Animation duration, default as 450 */
|
/** Animation duration, default as 450 */
|
||||||
@ -22,8 +22,10 @@ export default function scrollTo(y: number, options: ScrollToOptions = {}) {
|
|||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
const time = timestamp - startTime;
|
const time = timestamp - startTime;
|
||||||
const nextScrollTop = easeInOutCubic(time > duration ? duration : time, scrollTop, y, duration);
|
const nextScrollTop = easeInOutCubic(time > duration ? duration : time, scrollTop, y, duration);
|
||||||
if (container === window) {
|
if (isWindow(container)) {
|
||||||
window.scrollTo(window.pageXOffset, nextScrollTop);
|
(container as Window).scrollTo(window.pageXOffset, nextScrollTop);
|
||||||
|
} else if (container instanceof Document) {
|
||||||
|
container.documentElement.scrollTop = nextScrollTop;
|
||||||
} else {
|
} else {
|
||||||
(container as HTMLElement).scrollTop = nextScrollTop;
|
(container as HTMLElement).scrollTop = nextScrollTop;
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,47 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`renders ./components/back-top/demo/basic.md correctly 1`] = `
|
exports[`renders ./components/back-top/demo/basic.md correctly 1`] = `
|
||||||
<div>
|
Array [
|
||||||
Scroll down to see the bottom-right
|
<div
|
||||||
|
class="ant-back-top"
|
||||||
|
/>,
|
||||||
|
"Scroll down to see the bottom-right",
|
||||||
<strong
|
<strong
|
||||||
class="site-back-top-basic"
|
class="site-back-top-basic"
|
||||||
>
|
>
|
||||||
gray
|
gray
|
||||||
</strong>
|
</strong>,
|
||||||
button.
|
"button.",
|
||||||
</div>
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/back-top/demo/custom.md correctly 1`] = `
|
exports[`renders ./components/back-top/demo/custom.md correctly 1`] = `
|
||||||
<div>
|
<div
|
||||||
Scroll down to see the bottom-right
|
style="height:600vh;padding:8px"
|
||||||
<strong
|
>
|
||||||
style="color:#1088e9"
|
<div>
|
||||||
>
|
Scroll to bottom
|
||||||
blue
|
</div>
|
||||||
</strong>
|
<div>
|
||||||
button.
|
Scroll to bottom
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Scroll to bottom
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Scroll to bottom
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Scroll to bottom
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Scroll to bottom
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Scroll to bottom
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-back-top"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`BackTop rtl render component should be rendered correctly in RTL direction 1`] = `null`;
|
exports[`BackTop rtl render component should be rendered correctly in RTL direction 1`] = `
|
||||||
|
<div
|
||||||
|
class="ant-back-top ant-back-top-rtl"
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
@ -14,14 +14,16 @@ describe('BackTop', () => {
|
|||||||
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
||||||
window.scrollY = y;
|
window.scrollY = y;
|
||||||
window.pageYOffset = y;
|
window.pageYOffset = y;
|
||||||
|
document.documentElement.scrollTop = y;
|
||||||
});
|
});
|
||||||
window.scrollTo(0, 400);
|
window.scrollTo(0, 400);
|
||||||
|
expect(document.documentElement.scrollTop).toBe(400);
|
||||||
// trigger scroll manually
|
// trigger scroll manually
|
||||||
wrapper.instance().handleScroll();
|
wrapper.instance().handleScroll();
|
||||||
await sleep();
|
await sleep();
|
||||||
wrapper.find('.ant-back-top').simulate('click');
|
wrapper.find('.ant-back-top').simulate('click');
|
||||||
await sleep(500);
|
await sleep(500);
|
||||||
expect(window.pageYOffset).toBe(0);
|
expect(document.documentElement.scrollTop).toBe(0);
|
||||||
scrollToSpy.mockRestore();
|
scrollToSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -32,6 +34,7 @@ describe('BackTop', () => {
|
|||||||
window.scrollY = y;
|
window.scrollY = y;
|
||||||
window.pageYOffset = y;
|
window.pageYOffset = y;
|
||||||
});
|
});
|
||||||
|
document.dispatchEvent(new Event('scroll'));
|
||||||
window.scrollTo(0, 400);
|
window.scrollTo(0, 400);
|
||||||
// trigger scroll manually
|
// trigger scroll manually
|
||||||
wrapper.instance().handleScroll();
|
wrapper.instance().handleScroll();
|
||||||
@ -40,4 +43,28 @@ describe('BackTop', () => {
|
|||||||
expect(onClick).toHaveBeenCalled();
|
expect(onClick).toHaveBeenCalled();
|
||||||
scrollToSpy.mockRestore();
|
scrollToSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to update target', async () => {
|
||||||
|
const wrapper = mount(<BackTop />);
|
||||||
|
wrapper.instance().handleScroll = jest.fn();
|
||||||
|
const container = document.createElement('div');
|
||||||
|
wrapper.setProps({ target: () => container });
|
||||||
|
expect(wrapper.instance().handleScroll).toHaveBeenLastCalledWith({
|
||||||
|
target: container,
|
||||||
|
});
|
||||||
|
container.dispatchEvent(new Event('scroll'));
|
||||||
|
expect(wrapper.instance().handleScroll).toHaveBeenLastCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
currentTarget: container,
|
||||||
|
target: container,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('invalid target', async () => {
|
||||||
|
const onClick = jest.fn();
|
||||||
|
const wrapper = mount(<BackTop onClick={onClick} target={() => ({ documentElement: {} })} />);
|
||||||
|
wrapper.find('.ant-back-top').simulate('click');
|
||||||
|
expect(onClick).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -17,12 +17,12 @@ The most basic usage.
|
|||||||
import { BackTop } from 'antd';
|
import { BackTop } from 'antd';
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<div>
|
<>
|
||||||
<BackTop />
|
<BackTop />
|
||||||
Scroll down to see the bottom-right
|
Scroll down to see the bottom-right
|
||||||
<strong className="site-back-top-basic"> gray </strong>
|
<strong className="site-back-top-basic"> gray </strong>
|
||||||
button.
|
button.
|
||||||
</div>,
|
</>,
|
||||||
mountNode,
|
mountNode,
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
order: 1
|
order: 1
|
||||||
|
iframe: 400
|
||||||
title:
|
title:
|
||||||
zh-CN: 自定义样式
|
zh-CN: 自定义样式
|
||||||
en-US: Custom style
|
en-US: Custom style
|
||||||
@ -16,31 +17,30 @@ You can customize the style of the button, just note the size limit: no more tha
|
|||||||
```jsx
|
```jsx
|
||||||
import { BackTop } from 'antd';
|
import { BackTop } from 'antd';
|
||||||
|
|
||||||
|
const style = {
|
||||||
|
height: 40,
|
||||||
|
width: 40,
|
||||||
|
lineHeight: '40px',
|
||||||
|
borderRadius: 4,
|
||||||
|
backgroundColor: '#1088e9',
|
||||||
|
color: '#fff',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: 14,
|
||||||
|
};
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<div>
|
<div style={{ height: '600vh', padding: 8 }}>
|
||||||
|
<div>Scroll to bottom</div>
|
||||||
|
<div>Scroll to bottom</div>
|
||||||
|
<div>Scroll to bottom</div>
|
||||||
|
<div>Scroll to bottom</div>
|
||||||
|
<div>Scroll to bottom</div>
|
||||||
|
<div>Scroll to bottom</div>
|
||||||
|
<div>Scroll to bottom</div>
|
||||||
<BackTop>
|
<BackTop>
|
||||||
<div className="ant-back-top-inner">UP</div>
|
<div style={style}>UP</div>
|
||||||
</BackTop>
|
</BackTop>
|
||||||
Scroll down to see the bottom-right
|
|
||||||
<strong style={{ color: '#1088e9' }}> blue </strong>
|
|
||||||
button.
|
|
||||||
</div>,
|
</div>,
|
||||||
mountNode,
|
mountNode,
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
```css
|
|
||||||
#components-back-top-demo-custom .ant-back-top {
|
|
||||||
bottom: 100px;
|
|
||||||
}
|
|
||||||
#components-back-top-demo-custom .ant-back-top-inner {
|
|
||||||
height: 40px;
|
|
||||||
width: 40px;
|
|
||||||
line-height: 40px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: #1088e9;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
@ -3,18 +3,15 @@ import Animate from 'rc-animate';
|
|||||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import omit from 'omit.js';
|
import omit from 'omit.js';
|
||||||
|
import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
import getScroll from '../_util/getScroll';
|
import getScroll from '../_util/getScroll';
|
||||||
import scrollTo from '../_util/scrollTo';
|
import scrollTo from '../_util/scrollTo';
|
||||||
|
|
||||||
function getDefaultTarget() {
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BackTopProps {
|
export interface BackTopProps {
|
||||||
visibilityHeight?: number;
|
visibilityHeight?: number;
|
||||||
onClick?: React.MouseEventHandler<HTMLElement>;
|
onClick?: React.MouseEventHandler<HTMLElement>;
|
||||||
target?: () => HTMLElement | Window;
|
target?: () => HTMLElement | Window | Document;
|
||||||
prefixCls?: string;
|
prefixCls?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
@ -26,57 +23,101 @@ export default class BackTop extends React.Component<BackTopProps, any> {
|
|||||||
visibilityHeight: 400,
|
visibilityHeight: 400,
|
||||||
};
|
};
|
||||||
|
|
||||||
scrollEvent: any;
|
state = {
|
||||||
|
|
||||||
constructor(props: BackTopProps) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
visible: false,
|
visible: false,
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
scrollEvent: any;
|
||||||
|
|
||||||
|
node: HTMLDivElement;
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const getTarget = this.props.target || getDefaultTarget;
|
this.bindScrollEvent();
|
||||||
this.scrollEvent = addEventListener(getTarget(), 'scroll', this.handleScroll);
|
}
|
||||||
this.handleScroll();
|
|
||||||
|
componentDidUpdate(prevProps: BackTopProps) {
|
||||||
|
const { target } = this.props;
|
||||||
|
if (prevProps.target !== target) {
|
||||||
|
this.bindScrollEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
if (this.scrollEvent) {
|
if (this.scrollEvent) {
|
||||||
this.scrollEvent.remove();
|
this.scrollEvent.remove();
|
||||||
}
|
}
|
||||||
|
(this.handleScroll as any).cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bindScrollEvent() {
|
||||||
|
if (this.scrollEvent) {
|
||||||
|
this.scrollEvent.remove();
|
||||||
|
}
|
||||||
|
const { target } = this.props;
|
||||||
|
const getTarget = target || this.getDefaultTarget;
|
||||||
|
const container = getTarget();
|
||||||
|
this.scrollEvent = addEventListener(container, 'scroll', (e: React.UIEvent<HTMLElement>) => {
|
||||||
|
this.handleScroll(e);
|
||||||
|
});
|
||||||
|
this.handleScroll({
|
||||||
|
target: container,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getVisible() {
|
||||||
|
if ('visible' in this.props) {
|
||||||
|
return this.props.visible;
|
||||||
|
}
|
||||||
|
return this.state.visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDefaultTarget = () => {
|
||||||
|
return this.node && this.node.ownerDocument ? this.node.ownerDocument : window;
|
||||||
|
};
|
||||||
|
|
||||||
|
saveDivRef = (node: HTMLDivElement) => {
|
||||||
|
this.node = node;
|
||||||
|
};
|
||||||
|
|
||||||
scrollToTop = (e: React.MouseEvent<HTMLDivElement>) => {
|
scrollToTop = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||||
const { target = getDefaultTarget, onClick } = this.props;
|
const { onClick, target } = this.props;
|
||||||
scrollTo(0, {
|
scrollTo(0, {
|
||||||
getContainer: target,
|
getContainer: target || this.getDefaultTarget,
|
||||||
});
|
});
|
||||||
if (typeof onClick === 'function') {
|
if (typeof onClick === 'function') {
|
||||||
onClick(e);
|
onClick(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleScroll = () => {
|
@throttleByAnimationFrameDecorator()
|
||||||
const { visibilityHeight, target = getDefaultTarget } = this.props;
|
handleScroll(e: React.UIEvent<HTMLElement> | { target: any }) {
|
||||||
const scrollTop = getScroll(target(), true);
|
const { visibilityHeight = 0 } = this.props;
|
||||||
|
const scrollTop = getScroll(e.target, true);
|
||||||
this.setState({
|
this.setState({
|
||||||
visible: scrollTop > (visibilityHeight as number),
|
visible: scrollTop > visibilityHeight,
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
renderBackTop = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
|
|
||||||
const { prefixCls: customizePrefixCls, className = '', children } = this.props;
|
|
||||||
const prefixCls = getPrefixCls('back-top', customizePrefixCls);
|
|
||||||
const classString = classNames(prefixCls, className, {
|
|
||||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderChildren({ prefixCls }: { prefixCls: string }) {
|
||||||
|
const { children } = this.props;
|
||||||
const defaultElement = (
|
const defaultElement = (
|
||||||
<div className={`${prefixCls}-content`}>
|
<div className={`${prefixCls}-content`}>
|
||||||
<div className={`${prefixCls}-icon`} />
|
<div className={`${prefixCls}-icon`} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
return (
|
||||||
|
<Animate component="" transitionName="fade">
|
||||||
|
{this.getVisible() ? <div>{children || defaultElement}</div> : null}
|
||||||
|
</Animate>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderBackTop = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
|
||||||
|
const { prefixCls: customizePrefixCls, className = '' } = this.props;
|
||||||
|
const prefixCls = getPrefixCls('back-top', customizePrefixCls);
|
||||||
|
const classString = classNames(prefixCls, className, {
|
||||||
|
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||||
|
});
|
||||||
|
|
||||||
// fix https://fb.me/react-unknown-prop
|
// fix https://fb.me/react-unknown-prop
|
||||||
const divProps = omit(this.props, [
|
const divProps = omit(this.props, [
|
||||||
@ -88,18 +129,10 @@ export default class BackTop extends React.Component<BackTopProps, any> {
|
|||||||
'visible',
|
'visible',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const visible = 'visible' in this.props ? this.props.visible : this.state.visible;
|
|
||||||
|
|
||||||
const backTopBtn = visible ? (
|
|
||||||
<div {...divProps} className={classString} onClick={this.scrollToTop}>
|
|
||||||
{children || defaultElement}
|
|
||||||
</div>
|
|
||||||
) : null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Animate component="" transitionName="fade">
|
<div {...divProps} className={classString} onClick={this.scrollToTop} ref={this.saveDivRef}>
|
||||||
{backTopBtn}
|
{this.renderChildren({ prefixCls })}
|
||||||
</Animate>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -280,6 +280,7 @@ exports[`ConfigProvider components BackTop configProvider 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="config-back-top"
|
class="config-back-top"
|
||||||
>
|
>
|
||||||
|
<div>
|
||||||
<div
|
<div
|
||||||
class="config-back-top-content"
|
class="config-back-top-content"
|
||||||
>
|
>
|
||||||
@ -287,6 +288,7 @@ exports[`ConfigProvider components BackTop configProvider 1`] = `
|
|||||||
class="config-back-top-icon"
|
class="config-back-top-icon"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -294,6 +296,7 @@ exports[`ConfigProvider components BackTop normal 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="ant-back-top"
|
class="ant-back-top"
|
||||||
>
|
>
|
||||||
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-back-top-content"
|
class="ant-back-top-content"
|
||||||
>
|
>
|
||||||
@ -301,6 +304,7 @@ exports[`ConfigProvider components BackTop normal 1`] = `
|
|||||||
class="ant-back-top-icon"
|
class="ant-back-top-icon"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -308,6 +312,7 @@ exports[`ConfigProvider components BackTop prefixCls 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="prefix-BackTop"
|
class="prefix-BackTop"
|
||||||
>
|
>
|
||||||
|
<div>
|
||||||
<div
|
<div
|
||||||
class="prefix-BackTop-content"
|
class="prefix-BackTop-content"
|
||||||
>
|
>
|
||||||
@ -315,6 +320,7 @@ exports[`ConfigProvider components BackTop prefixCls 1`] = `
|
|||||||
class="prefix-BackTop-icon"
|
class="prefix-BackTop-icon"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -73,10 +73,16 @@ describe('Upload List', () => {
|
|||||||
drawImageCallback = null;
|
drawImageCallback = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let open;
|
||||||
|
beforeAll(() => {
|
||||||
|
open = jest.spyOn(window, 'open').mockImplementation(() => {});
|
||||||
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
window.URL.createObjectURL = originCreateObjectURL;
|
window.URL.createObjectURL = originCreateObjectURL;
|
||||||
imageSpy.mockRestore();
|
imageSpy.mockRestore();
|
||||||
canvasSpy.mockRestore();
|
canvasSpy.mockRestore();
|
||||||
|
open.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/4653
|
// https://github.com/ant-design/ant-design/issues/4653
|
||||||
@ -118,11 +124,7 @@ describe('Upload List', () => {
|
|||||||
</Upload>,
|
</Upload>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-upload-list-item').length).toBe(2);
|
expect(wrapper.find('.ant-upload-list-item').length).toBe(2);
|
||||||
wrapper
|
wrapper.find('.ant-upload-list-item').at(0).find('.anticon-delete').simulate('click');
|
||||||
.find('.ant-upload-list-item')
|
|
||||||
.at(0)
|
|
||||||
.find('.anticon-delete')
|
|
||||||
.simulate('click');
|
|
||||||
await sleep(400);
|
await sleep(400);
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(wrapper.find('.ant-upload-list-item').hostNodes().length).toBe(1);
|
expect(wrapper.find('.ant-upload-list-item').hostNodes().length).toBe(1);
|
||||||
@ -243,15 +245,9 @@ describe('Upload List', () => {
|
|||||||
<button type="button">upload</button>
|
<button type="button">upload</button>
|
||||||
</Upload>,
|
</Upload>,
|
||||||
);
|
);
|
||||||
wrapper
|
wrapper.find('.anticon-eye').at(0).simulate('click');
|
||||||
.find('.anticon-eye')
|
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
expect(handlePreview).toHaveBeenCalledWith(fileList[0]);
|
expect(handlePreview).toHaveBeenCalledWith(fileList[0]);
|
||||||
wrapper
|
wrapper.find('.anticon-eye').at(1).simulate('click');
|
||||||
.find('.anticon-eye')
|
|
||||||
.at(1)
|
|
||||||
.simulate('click');
|
|
||||||
expect(handlePreview).toHaveBeenCalledWith(fileList[1]);
|
expect(handlePreview).toHaveBeenCalledWith(fileList[1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -268,15 +264,9 @@ describe('Upload List', () => {
|
|||||||
<button type="button">upload</button>
|
<button type="button">upload</button>
|
||||||
</Upload>,
|
</Upload>,
|
||||||
);
|
);
|
||||||
wrapper
|
wrapper.find('.anticon-delete').at(0).simulate('click');
|
||||||
.find('.anticon-delete')
|
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
expect(handleRemove).toHaveBeenCalledWith(fileList[0]);
|
expect(handleRemove).toHaveBeenCalledWith(fileList[0]);
|
||||||
wrapper
|
wrapper.find('.anticon-delete').at(1).simulate('click');
|
||||||
.find('.anticon-delete')
|
|
||||||
.at(1)
|
|
||||||
.simulate('click');
|
|
||||||
expect(handleRemove).toHaveBeenCalledWith(fileList[1]);
|
expect(handleRemove).toHaveBeenCalledWith(fileList[1]);
|
||||||
await sleep();
|
await sleep();
|
||||||
expect(handleChange.mock.calls.length).toBe(2);
|
expect(handleChange.mock.calls.length).toBe(2);
|
||||||
@ -303,10 +293,7 @@ describe('Upload List', () => {
|
|||||||
<button type="button">upload</button>
|
<button type="button">upload</button>
|
||||||
</Upload>,
|
</Upload>,
|
||||||
);
|
);
|
||||||
wrapper
|
wrapper.find('.anticon-download').at(0).simulate('click');
|
||||||
.find('.anticon-download')
|
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support no onDownload', async () => {
|
it('should support no onDownload', async () => {
|
||||||
@ -328,10 +315,7 @@ describe('Upload List', () => {
|
|||||||
<button type="button">upload</button>
|
<button type="button">upload</button>
|
||||||
</Upload>,
|
</Upload>,
|
||||||
);
|
);
|
||||||
wrapper
|
wrapper.find('.anticon-download').at(0).simulate('click');
|
||||||
.find('.anticon-download')
|
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should generate thumbUrl from file', () => {
|
describe('should generate thumbUrl from file', () => {
|
||||||
@ -504,16 +488,10 @@ describe('Upload List', () => {
|
|||||||
<button type="button">upload</button>
|
<button type="button">upload</button>
|
||||||
</Upload>,
|
</Upload>,
|
||||||
);
|
);
|
||||||
wrapper
|
wrapper.find('.custom-delete').at(0).simulate('click');
|
||||||
.find('.custom-delete')
|
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
expect(handleRemove).toHaveBeenCalledWith(fileList[0]);
|
expect(handleRemove).toHaveBeenCalledWith(fileList[0]);
|
||||||
expect(myClick).toHaveBeenCalled();
|
expect(myClick).toHaveBeenCalled();
|
||||||
wrapper
|
wrapper.find('.custom-delete').at(1).simulate('click');
|
||||||
.find('.custom-delete')
|
|
||||||
.at(1)
|
|
||||||
.simulate('click');
|
|
||||||
expect(handleRemove).toHaveBeenCalledWith(fileList[1]);
|
expect(handleRemove).toHaveBeenCalledWith(fileList[1]);
|
||||||
expect(myClick).toHaveBeenCalled();
|
expect(myClick).toHaveBeenCalled();
|
||||||
await sleep();
|
await sleep();
|
||||||
|
Loading…
Reference in New Issue
Block a user