|
|
@ -1,10 +1,9 @@ |
|
|
|
import type { CSSProperties } from 'react'; |
|
|
|
import React, { useEffect, useRef } from 'react'; |
|
|
|
import type { InternalAffixClass } from '..'; |
|
|
|
import Affix from '..'; |
|
|
|
import accessibilityTest from '../../../tests/shared/accessibilityTest'; |
|
|
|
import rtlTest from '../../../tests/shared/rtlTest'; |
|
|
|
import { render, triggerResize, waitFakeTimer } from '../../../tests/utils'; |
|
|
|
import { render, waitFakeTimer } from '../../../tests/utils'; |
|
|
|
import Button from '../../button'; |
|
|
|
|
|
|
|
const events: Partial<Record<keyof HTMLElementEventMap, (ev: Partial<Event>) => void>> = {}; |
|
|
@ -14,11 +13,9 @@ interface AffixProps { |
|
|
|
offsetBottom?: number; |
|
|
|
style?: CSSProperties; |
|
|
|
onChange?: () => void; |
|
|
|
onTestUpdatePosition?: () => void; |
|
|
|
getInstance?: (inst: InternalAffixClass) => void; |
|
|
|
} |
|
|
|
|
|
|
|
const AffixMounter: React.FC<AffixProps> = ({ getInstance, ...restProps }) => { |
|
|
|
const AffixMounter: React.FC<AffixProps> = (props) => { |
|
|
|
const container = useRef<HTMLDivElement>(null); |
|
|
|
useEffect(() => { |
|
|
|
if (container.current) { |
|
|
@ -31,8 +28,8 @@ const AffixMounter: React.FC<AffixProps> = ({ getInstance, ...restProps }) => { |
|
|
|
}, []); |
|
|
|
return ( |
|
|
|
<div ref={container} className="container"> |
|
|
|
<Affix className="fixed" ref={getInstance} target={() => container.current} {...restProps}> |
|
|
|
<Button type="primary">Fixed at the top of container</Button> |
|
|
|
<Affix className="fixed" target={() => container.current} {...props}> |
|
|
|
<Button>Fixed at the top of container</Button> |
|
|
|
</Affix> |
|
|
|
</div> |
|
|
|
); |
|
|
@ -124,36 +121,6 @@ describe('Affix Render', () => { |
|
|
|
}); |
|
|
|
|
|
|
|
describe('updatePosition when target changed', () => { |
|
|
|
it('function change', async () => { |
|
|
|
document.body.innerHTML = '<div id="mounter" />'; |
|
|
|
const container = document.getElementById('mounter'); |
|
|
|
const getTarget = () => container; |
|
|
|
let affixInstance: InternalAffixClass; |
|
|
|
const { rerender } = render( |
|
|
|
<Affix |
|
|
|
ref={(node) => { |
|
|
|
affixInstance = node as InternalAffixClass; |
|
|
|
}} |
|
|
|
target={getTarget} |
|
|
|
> |
|
|
|
{null} |
|
|
|
</Affix>, |
|
|
|
); |
|
|
|
rerender( |
|
|
|
<Affix |
|
|
|
ref={(node) => { |
|
|
|
affixInstance = node as InternalAffixClass; |
|
|
|
}} |
|
|
|
target={() => null} |
|
|
|
> |
|
|
|
{null} |
|
|
|
</Affix>, |
|
|
|
); |
|
|
|
expect(affixInstance!.state.status).toBe(0); |
|
|
|
expect(affixInstance!.state.affixStyle).toBe(undefined); |
|
|
|
expect(affixInstance!.state.placeholderStyle).toBe(undefined); |
|
|
|
}); |
|
|
|
|
|
|
|
it('check position change before measure', async () => { |
|
|
|
const { container } = render( |
|
|
|
<> |
|
|
@ -169,80 +136,5 @@ describe('Affix Render', () => { |
|
|
|
await movePlaceholder(1000); |
|
|
|
expect(container.querySelector('.ant-affix')).toBeTruthy(); |
|
|
|
}); |
|
|
|
|
|
|
|
it('do not measure when hidden', async () => { |
|
|
|
let affixInstance: InternalAffixClass | null = null; |
|
|
|
|
|
|
|
const { rerender } = render( |
|
|
|
<AffixMounter |
|
|
|
getInstance={(inst) => { |
|
|
|
affixInstance = inst; |
|
|
|
}} |
|
|
|
offsetBottom={0} |
|
|
|
/>, |
|
|
|
); |
|
|
|
await waitFakeTimer(); |
|
|
|
const firstAffixStyle = affixInstance!.state.affixStyle; |
|
|
|
|
|
|
|
rerender( |
|
|
|
<AffixMounter |
|
|
|
getInstance={(inst) => { |
|
|
|
affixInstance = inst; |
|
|
|
}} |
|
|
|
offsetBottom={0} |
|
|
|
style={{ display: 'none' }} |
|
|
|
/>, |
|
|
|
); |
|
|
|
await waitFakeTimer(); |
|
|
|
const secondAffixStyle = affixInstance!.state.affixStyle; |
|
|
|
|
|
|
|
expect(firstAffixStyle).toEqual(secondAffixStyle); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
describe('updatePosition when size changed', () => { |
|
|
|
it('add class automatically', async () => { |
|
|
|
document.body.innerHTML = '<div id="mounter" />'; |
|
|
|
|
|
|
|
let affixInstance: InternalAffixClass | null = null; |
|
|
|
render( |
|
|
|
<AffixMounter |
|
|
|
getInstance={(inst) => { |
|
|
|
affixInstance = inst; |
|
|
|
}} |
|
|
|
offsetBottom={0} |
|
|
|
/>, |
|
|
|
{ |
|
|
|
container: document.getElementById('mounter')!, |
|
|
|
}, |
|
|
|
); |
|
|
|
|
|
|
|
await waitFakeTimer(); |
|
|
|
await movePlaceholder(300); |
|
|
|
expect(affixInstance!.state.affixStyle).toBeTruthy(); |
|
|
|
}); |
|
|
|
|
|
|
|
// Trigger inner and outer element for the two <ResizeObserver>s.
|
|
|
|
[ |
|
|
|
'.ant-btn', // inner
|
|
|
|
'.fixed', // outer
|
|
|
|
].forEach((selector) => { |
|
|
|
it(`trigger listener when size change: ${selector}`, async () => { |
|
|
|
const updateCalled = jest.fn(); |
|
|
|
const { container } = render( |
|
|
|
<AffixMounter offsetBottom={0} onTestUpdatePosition={updateCalled} />, |
|
|
|
{ |
|
|
|
container: document.getElementById('mounter')!, |
|
|
|
}, |
|
|
|
); |
|
|
|
|
|
|
|
updateCalled.mockReset(); |
|
|
|
triggerResize(container.querySelector(selector)!); |
|
|
|
|
|
|
|
await waitFakeTimer(); |
|
|
|
|
|
|
|
expect(updateCalled).toHaveBeenCalled(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|