Skip to content

Commit 8e6f526

Browse files
authored
fix: panel not follow when scroll is visible (#76)
* fix: panel not follow when scroll is visible * test: add scroll test case * chore: update snapshot
1 parent 9f65afb commit 8e6f526

File tree

4 files changed

+231
-2
lines changed

4 files changed

+231
-2
lines changed

src/hooks/useTarget.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,12 @@ export default function useTarget(
8585
updatePos();
8686
// update when window resize
8787
window.addEventListener('resize', updatePos);
88+
// update when `document.body.style.overflow` is set to visible
89+
// by default, it will be set to hidden
90+
window.addEventListener('scroll', updatePos);
8891
return () => {
8992
window.removeEventListener('resize', updatePos);
93+
window.removeEventListener('scroll', updatePos);
9094
};
9195
}, [targetElement, open, updatePos]);
9296

tests/__snapshots__/index.test.tsx.snap

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,161 @@ exports[`Tour should update position when window resize 1`] = `
12801280
</body>
12811281
`;
12821282

1283+
exports[`Tour should update position when window scroll 1`] = `
1284+
<body>
1285+
<div>
1286+
<div
1287+
style="width: 100%;"
1288+
>
1289+
<button
1290+
class="btn2"
1291+
>
1292+
按钮
1293+
</button>
1294+
</div>
1295+
</div>
1296+
<div>
1297+
<div
1298+
class="rc-tour-mask"
1299+
style="position: fixed; left: 0px; right: 0px; top: 0px; bottom: 0px; z-index: 1001; pointer-events: none;"
1300+
>
1301+
<svg
1302+
style="width: 100%; height: 100%;"
1303+
>
1304+
<defs>
1305+
<mask
1306+
id="rc-tour-mask-test-id"
1307+
>
1308+
<rect
1309+
fill="white"
1310+
height="100vh"
1311+
width="100vw"
1312+
x="0"
1313+
y="0"
1314+
/>
1315+
<rect
1316+
class=""
1317+
fill="black"
1318+
height="192"
1319+
rx="2"
1320+
width="242"
1321+
x="74"
1322+
y="794"
1323+
/>
1324+
</mask>
1325+
</defs>
1326+
<rect
1327+
fill="rgba(0,0,0,0.5)"
1328+
height="100%"
1329+
mask="url(#rc-tour-mask-test-id)"
1330+
width="100%"
1331+
x="0"
1332+
y="0"
1333+
/>
1334+
<rect
1335+
fill="transparent"
1336+
height="794"
1337+
pointer-events="auto"
1338+
width="100%"
1339+
x="0"
1340+
y="0"
1341+
/>
1342+
<rect
1343+
fill="transparent"
1344+
height="100%"
1345+
pointer-events="auto"
1346+
width="74"
1347+
x="0"
1348+
y="0"
1349+
/>
1350+
<rect
1351+
fill="transparent"
1352+
height="calc(100% - 986px)"
1353+
pointer-events="auto"
1354+
width="100%"
1355+
x="0"
1356+
y="986"
1357+
/>
1358+
<rect
1359+
fill="transparent"
1360+
height="100%"
1361+
pointer-events="auto"
1362+
width="calc(100% - 316px)"
1363+
x="316"
1364+
y="0"
1365+
/>
1366+
</svg>
1367+
</div>
1368+
</div>
1369+
<div>
1370+
<div
1371+
class="rc-tour-target-placeholder"
1372+
style="left: 74px; top: 794px; width: 242px; height: 192px; position: fixed; pointer-events: none;"
1373+
/>
1374+
</div>
1375+
<div>
1376+
<div
1377+
class="rc-tour rc-tour-placement-bottom"
1378+
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box; z-index: 1001;"
1379+
>
1380+
<div
1381+
class="rc-tour-arrow"
1382+
style="position: absolute;"
1383+
/>
1384+
<div
1385+
class="rc-tour-pannel"
1386+
>
1387+
<div
1388+
class="rc-tour-section"
1389+
>
1390+
<button
1391+
aria-label="Close"
1392+
class="rc-tour-close"
1393+
type="button"
1394+
>
1395+
<span
1396+
class="rc-tour-close-x"
1397+
>
1398+
×
1399+
</span>
1400+
</button>
1401+
<div
1402+
class="rc-tour-header"
1403+
>
1404+
<div
1405+
class="rc-tour-title"
1406+
>
1407+
创建
1408+
</div>
1409+
</div>
1410+
<div
1411+
class="rc-tour-description"
1412+
>
1413+
创建一条数据
1414+
</div>
1415+
<div
1416+
class="rc-tour-footer"
1417+
>
1418+
<div
1419+
class="rc-tour-sliders"
1420+
/>
1421+
<div
1422+
class="rc-tour-actions"
1423+
>
1424+
<button
1425+
class="rc-tour-finish-btn"
1426+
>
1427+
Finish
1428+
</button>
1429+
</div>
1430+
</div>
1431+
</div>
1432+
</div>
1433+
</div>
1434+
</div>
1435+
</body>
1436+
`;
1437+
12831438
exports[`Tour showArrow should show tooltip arrow default 1`] = `
12841439
<body>
12851440
<div>

tests/index.test.tsx

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { TourProps } from '../src/index';
77
import Tour from '../src/index';
88
import { getPlacements, placements } from '../src/placements';
99
import { getPlacement } from '../src/util';
10-
import { resizeWindow } from './utils';
10+
import { resizeWindow, scrollWindow } from './utils';
1111

1212
const mockBtnRect = (
1313
rect: {
@@ -1225,4 +1225,68 @@ describe('Tour', () => {
12251225
// Check container has children
12261226
expect(children).toBeTruthy();
12271227
});
1228+
1229+
it('should update position when window scroll', async () => {
1230+
mockBtnRect({
1231+
x: 80,
1232+
y: 333,
1233+
width: 230,
1234+
height: 180,
1235+
});
1236+
const Demo = () => {
1237+
const btnRef = useRef<HTMLButtonElement>(null);
1238+
1239+
return (
1240+
<div style={{ width: '100%' }}>
1241+
<button
1242+
className="btn2"
1243+
ref={btnRef}
1244+
onClick={() => {
1245+
mockBtnRect({
1246+
x: 80,
1247+
y: 800,
1248+
width: 230,
1249+
height: 180,
1250+
});
1251+
scrollWindow(0, 800);
1252+
}}
1253+
>
1254+
按钮
1255+
</button>
1256+
<Tour
1257+
open
1258+
placement={'bottom'}
1259+
steps={[
1260+
{
1261+
title: '创建',
1262+
description: '创建一条数据',
1263+
target: () => btnRef.current,
1264+
},
1265+
]}
1266+
/>
1267+
</div>
1268+
);
1269+
};
1270+
const { baseElement, unmount } = render(<Demo />);
1271+
expect(
1272+
baseElement.querySelector('.rc-tour-target-placeholder'),
1273+
).toHaveStyle('left: 74px; top: 327px; width: 242px; height: 192px;');
1274+
fireEvent.click(baseElement.querySelector('.btn2'));
1275+
await act(() => {
1276+
jest.runAllTimers();
1277+
});
1278+
expect(
1279+
baseElement.querySelector('.rc-tour-target-placeholder'),
1280+
).toHaveStyle('left: 74px; top: 794px; width: 242px; height: 192px;');
1281+
1282+
expect(baseElement).toMatchSnapshot();
1283+
1284+
unmount();
1285+
mockBtnRect({
1286+
x: 0,
1287+
y: 0,
1288+
width: 0,
1289+
height: 0,
1290+
});
1291+
});
12281292
});

tests/utils.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@ export const resizeWindow = (x: number, y: number) => {
44
// @ts-ignore
55
window.innerHeight = y;
66
window.dispatchEvent(new Event('resize'));
7-
};
7+
};
8+
9+
10+
export const scrollWindow = (x: number, y: number) => {
11+
window.scrollTo(x, y);
12+
window.dispatchEvent(new Event('scroll'))
13+
}

0 commit comments

Comments
 (0)