Skip to content

Commit b500123

Browse files
authored
chore: When target invisible, not trigger align (#336)
* docs: update demo * test: update test cas * test: add test case * test: fix test case
1 parent 763af1b commit b500123

File tree

5 files changed

+86
-8
lines changed

5 files changed

+86
-8
lines changed

docs/examples/container.tsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export default () => {
6161
console.log('Demo Render!');
6262

6363
const [scale, setScale] = React.useState('1');
64+
const [targetVisible, setTargetVisible] = React.useState(true);
6465

6566
const rootRef = React.useRef<HTMLDivElement>();
6667
const popHolderRef = React.useRef<HTMLDivElement>();
@@ -78,17 +79,28 @@ export default () => {
7879
ref={rootRef}
7980
style={{ background: 'rgba(0, 0, 255, 0.1)', padding: 16 }}
8081
>
81-
<input
82-
type="number"
83-
value={scale}
84-
onChange={(e) => setScale(e.target.value)}
82+
<div
8583
style={{
8684
position: 'fixed',
8785
left: 0,
8886
top: 0,
8987
zIndex: 9999,
9088
}}
91-
/>
89+
>
90+
<input
91+
type="number"
92+
value={scale}
93+
onChange={(e) => setScale(e.target.value)}
94+
/>
95+
<button
96+
type="button"
97+
onClick={() => {
98+
setTargetVisible((v) => !v);
99+
}}
100+
>
101+
Target Visible: ({String(targetVisible)})
102+
</button>
103+
</div>
92104
<div
93105
id="demo-holder"
94106
ref={popHolderRef}
@@ -149,13 +161,13 @@ export default () => {
149161
>
150162
<span
151163
style={{
152-
display: 'inline-block',
153164
background: 'green',
154165
color: '#FFF',
155166
paddingBlock: 30,
156167
paddingInline: 70,
157168
opacity: 0.9,
158169
transform: 'scale(0.6)',
170+
display: targetVisible ? 'inline-block' : 'none',
159171
}}
160172
>
161173
Target

src/hooks/useAlign.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,11 @@ export default function useAlign(
226226
);
227227

228228
// No need to align since it's not visible in view
229-
if (scaleX === 0 || scaleY === 0) {
229+
if (
230+
scaleX === 0 ||
231+
scaleY === 0 ||
232+
(target instanceof HTMLElement && !target.offsetParent)
233+
) {
230234
return;
231235
}
232236

tests/align.test.tsx

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { act, cleanup, fireEvent, render } from '@testing-library/react';
22
import { spyElementPrototypes } from 'rc-util/lib/test/domHook';
33
import React from 'react';
4-
import type { TriggerProps } from '../src';
4+
import type { TriggerProps, TriggerRef } from '../src';
55
import Trigger from '../src';
66
import { awaitFakeTimer } from './util';
77

@@ -14,6 +14,8 @@ export const triggerResize = (target: Element) => {
1414
};
1515

1616
describe('Trigger.Align', () => {
17+
let targetVisible = true;
18+
1719
beforeAll(() => {
1820
spyElementPrototypes(HTMLDivElement, {
1921
getBoundingClientRect: () => ({
@@ -23,9 +25,16 @@ describe('Trigger.Align', () => {
2325
height: 100,
2426
}),
2527
});
28+
29+
spyElementPrototypes(HTMLElement, {
30+
offsetParent: {
31+
get: () => (targetVisible ? document.body : null),
32+
},
33+
});
2634
});
2735

2836
beforeEach(() => {
37+
targetVisible = true;
2938
jest.useFakeTimers();
3039
});
3140

@@ -130,4 +139,41 @@ describe('Trigger.Align', () => {
130139
document.querySelector('.rc-trigger-popup-placement-top'),
131140
).toBeTruthy();
132141
});
142+
143+
it('invisible should not align', async () => {
144+
const onPopupAlign = jest.fn();
145+
const triggerRef = React.createRef<TriggerRef>();
146+
147+
render(
148+
<Trigger
149+
popupVisible
150+
popup={<span className="bamboo" />}
151+
popupAlign={{}}
152+
onPopupAlign={onPopupAlign}
153+
ref={triggerRef}
154+
>
155+
<span />
156+
</Trigger>,
157+
);
158+
159+
await awaitFakeTimer();
160+
161+
expect(onPopupAlign).toHaveBeenCalled();
162+
onPopupAlign.mockReset();
163+
164+
for (let i = 0; i < 10; i += 1) {
165+
triggerRef.current!.forceAlign();
166+
167+
await awaitFakeTimer();
168+
expect(onPopupAlign).toHaveBeenCalled();
169+
onPopupAlign.mockReset();
170+
}
171+
172+
// Make invisible
173+
targetVisible = false;
174+
175+
triggerRef.current!.forceAlign();
176+
await awaitFakeTimer();
177+
expect(onPopupAlign).not.toHaveBeenCalled();
178+
});
133179
});

tests/arrow.test.jsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ import {
88
import Trigger from '../src';
99

1010
describe('Trigger.Arrow', () => {
11+
beforeAll(() => {
12+
spyElementPrototypes(HTMLElement, {
13+
offsetParent: {
14+
get: () => document.body,
15+
},
16+
});
17+
});
18+
1119
beforeEach(() => {
1220
jest.useFakeTimers();
1321
});

tests/basic.test.jsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ import Trigger from '../src';
88
import { awaitFakeTimer, placementAlignMap } from './util';
99

1010
describe('Trigger.Basic', () => {
11+
beforeAll(() => {
12+
spyElementPrototypes(HTMLElement, {
13+
offsetParent: {
14+
get: () => document.body,
15+
},
16+
});
17+
});
18+
1119
beforeEach(() => {
1220
jest.useFakeTimers();
1321
});

0 commit comments

Comments
 (0)