Skip to content

Commit 8e48450

Browse files
committed
update
1 parent fac2f2d commit 8e48450

5 files changed

Lines changed: 168 additions & 1 deletion

File tree

tests/arrow.test.jsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
spyElementPrototypes,
77
} from '@rc-component/util/lib/test/domHook';
88
import Trigger from '../src';
9+
import Arrow from '../src/Popup/Arrow';
910

1011
describe('Trigger.Arrow', () => {
1112
beforeAll(() => {
@@ -42,6 +43,22 @@ describe('Trigger.Arrow', () => {
4243
);
4344
});
4445

46+
it('uses default arrow options and position', () => {
47+
render(
48+
<Arrow
49+
prefixCls="rc-trigger-popup"
50+
align={{ points: ['tl', 'bl'] }}
51+
arrow={undefined}
52+
arrowPos={{}}
53+
/>,
54+
);
55+
56+
expect(document.querySelector('.rc-trigger-popup-arrow')).toHaveStyle({
57+
left: 0,
58+
top: 0,
59+
});
60+
});
61+
4562
describe('direction', () => {
4663
let divSpy;
4764
let windowSpy;

tests/basic.test.jsx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,67 @@ describe('Trigger.Basic', () => {
298298
expect(isPopupHidden()).toBeTruthy();
299299
});
300300

301+
it('cancels refresh close detection when mouse returns to safe hover area', () => {
302+
const { container } = render(
303+
<Trigger
304+
action={['hover']}
305+
mouseLeaveDelay={0.1}
306+
popup={<strong>trigger</strong>}
307+
>
308+
<div className="target">hover</div>
309+
</Trigger>,
310+
);
311+
312+
const target = container.querySelector('.target');
313+
314+
fireEvent.mouseEnter(target, { clientX: 50, clientY: 10 });
315+
act(() => jest.runAllTimers());
316+
317+
const popup = document.querySelector('.rc-trigger-popup');
318+
319+
mockRect(target, { left: 0, top: 0, width: 100, height: 20 });
320+
mockRect(popup, { left: 20, top: 60, width: 60, height: 30 });
321+
322+
fireEvent.mouseLeave(target, { clientX: 50, clientY: 20 });
323+
fireEvent.mouseMove(document, { clientX: 150, clientY: 40 });
324+
fireEvent.mouseMove(document, { clientX: 50, clientY: 40 });
325+
326+
act(() => jest.advanceTimersByTime(100));
327+
328+
expect(isPopupHidden()).toBeFalsy();
329+
});
330+
331+
it('keeps pending refresh close detection while mouse remains unsafe', () => {
332+
const { container } = render(
333+
<Trigger
334+
action={['hover']}
335+
mouseLeaveDelay={0.1}
336+
popup={<strong>trigger</strong>}
337+
>
338+
<div className="target">hover</div>
339+
</Trigger>,
340+
);
341+
342+
const target = container.querySelector('.target');
343+
344+
fireEvent.mouseEnter(target, { clientX: 50, clientY: 10 });
345+
act(() => jest.runAllTimers());
346+
347+
const popup = document.querySelector('.rc-trigger-popup');
348+
349+
mockRect(target, { left: 0, top: 0, width: 100, height: 20 });
350+
mockRect(popup, { left: 20, top: 60, width: 60, height: 30 });
351+
352+
fireEvent.mouseLeave(target, { clientX: 50, clientY: 20 });
353+
fireEvent.mouseMove(document, { clientX: 50, clientY: 150 });
354+
fireEvent.mouseMove(document, { clientX: 50, clientY: 150 });
355+
356+
mockRect(popup, { left: 20, top: 60, width: 60, height: 200 });
357+
act(() => jest.advanceTimersByTime(100));
358+
359+
expect(isPopupHidden()).toBeFalsy();
360+
});
361+
301362
it('waits for mousemove to start refresh close detection after safe hover area disappears', () => {
302363
const { container } = render(
303364
<Trigger

tests/flip.test.tsx

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { spyElementPrototypes } from '@rc-component/util/lib/test/domHook';
44
import * as React from 'react';
55
import type { AlignType, TriggerProps } from '../src';
66
import Trigger from '../src';
7-
import { getVisibleArea } from '../src/util';
7+
import { collectScroller, getVisibleArea } from '../src/util';
88

99
const flush = async () => {
1010
for (let i = 0; i < 10; i += 1) {
@@ -366,6 +366,47 @@ describe('Trigger.Align', () => {
366366
window.getComputedStyle = oriGetComputedStyle;
367367
});
368368

369+
it('visible area skips document body and html elements', () => {
370+
const initArea = {
371+
left: 0,
372+
right: 500,
373+
top: 0,
374+
bottom: 500,
375+
};
376+
377+
expect(getVisibleArea(initArea)).toEqual(initArea);
378+
expect(
379+
getVisibleArea(initArea, [document.body, document.documentElement]),
380+
).toEqual(initArea);
381+
});
382+
383+
it('handles elements without a document window', () => {
384+
const detachedDocument = document.implementation.createHTMLDocument();
385+
const scroller = detachedDocument.createElement('div');
386+
const child = detachedDocument.createElement('div');
387+
388+
detachedDocument.body.appendChild(scroller);
389+
scroller.appendChild(child);
390+
391+
expect(collectScroller(child)).toEqual([]);
392+
expect(
393+
getVisibleArea(
394+
{
395+
left: 0,
396+
right: 500,
397+
top: 0,
398+
bottom: 500,
399+
},
400+
[scroller],
401+
),
402+
).toEqual({
403+
left: 0,
404+
right: 100,
405+
top: 0,
406+
bottom: 100,
407+
});
408+
});
409+
369410
// e.g. adjustY + shiftX may make popup out but push back in screen
370411
// which should keep flip
371412
/*

tests/safeHover.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
getSafeHoverAreaPolygons,
23
getSafeHoverSide,
34
isPointInSafeHoverArea,
45
type SafeHoverRect,
@@ -138,4 +139,22 @@ describe('safeHover util', () => {
138139
),
139140
).toBe(true);
140141
});
142+
143+
it('supports custom safe hover buffer', () => {
144+
expect(
145+
getSafeHoverAreaPolygons(
146+
[50, 20],
147+
rect(0, 0, 100, 20),
148+
rect(20, 60, 60, 30),
149+
),
150+
).toHaveLength(2);
151+
expect(
152+
getSafeHoverAreaPolygons(
153+
[50, 20],
154+
rect(0, 0, 100, 20),
155+
rect(20, 60, 60, 30),
156+
4,
157+
),
158+
).toHaveLength(2);
159+
});
141160
});

tests/useOffsetStyle.test.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { renderHook } from '@testing-library/react';
2+
import useOffsetStyle from '../src/hooks/useOffsetStyle';
3+
4+
describe('useOffsetStyle', () => {
5+
it('uses right and bottom offsets with dynamic inset alignment', () => {
6+
const { result } = renderHook(() =>
7+
useOffsetStyle(
8+
false,
9+
true,
10+
true,
11+
{
12+
points: ['br', 'tr'],
13+
dynamicInset: true,
14+
},
15+
12,
16+
34,
17+
56,
18+
78,
19+
),
20+
);
21+
22+
expect(result.current).toEqual({
23+
left: 'auto',
24+
top: 'auto',
25+
right: 12,
26+
bottom: 34,
27+
});
28+
});
29+
});

0 commit comments

Comments
 (0)