Skip to content

Commit 21ef954

Browse files
authored
Merge pull request #364 from seatable/opt-color-picker-when-modal-portaled
update
2 parents 3a739e7 + a25992c commit 21ef954

File tree

1 file changed

+55
-23
lines changed
  • src/DTableColorPicker/ColorPickerPortal

1 file changed

+55
-23
lines changed

src/DTableColorPicker/ColorPickerPortal/index.js

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,78 @@
1-
import React, { useEffect, useRef, useState } from 'react';
1+
import React, { useEffect, useRef, useState, useCallback } from 'react';
22
import ReactDOM from 'react-dom';
33
import { throttle } from '../../utils/utils';
44

5-
export default function ColorPickerPortal({ target, scrollContainerId, throttleDelay, children }) {
6-
5+
export default function ColorPickerPortal({ target, scrollContainerId, throttleDelay = 16, children }) {
76
const containerRef = useRef(null);
8-
const [position, setPosition] = useState({ top: 0, left: 0 });
7+
const [isPositioned, setIsPositioned] = useState(false);
8+
const [position, setPosition] = useState(() => {
9+
return { top: '-9999px', left: '-9999px', visibility: 'hidden' };
10+
});
911

10-
useEffect(() => {
12+
const updatePosition = useCallback(() => {
1113
if (!target || !containerRef.current) return;
12-
const updatePosition = () => {
13-
const targetRect = target.getBoundingClientRect();
14-
const { top: spaceAbove, left } = targetRect;
15-
const portalRectHeight = containerRef.current.clientHeight;
16-
if (spaceAbove < portalRectHeight) {
17-
setPosition({ top: `calc(${spaceAbove}px + 2.375rem)`, left: left + 1 + 'px' });
18-
return;
19-
}
20-
setPosition({ top: `calc(${spaceAbove - portalRectHeight}px)`, left: left + 1 + 'px' });
14+
15+
const targetRect = target.getBoundingClientRect();
16+
const { top: spaceAbove, left } = targetRect;
17+
const portalRectHeight = containerRef.current.clientHeight;
18+
19+
const newPosition = {
20+
left: `${left + 1}px`,
21+
visibility: 'visible',
2122
};
22-
updatePosition();
23+
24+
if (spaceAbove < portalRectHeight) {
25+
newPosition.top = `calc(${spaceAbove}px + 2.375rem)`;
26+
} else {
27+
newPosition.top = `calc(${spaceAbove - portalRectHeight}px)`;
28+
}
29+
30+
setPosition(prev => ({
31+
...prev,
32+
...newPosition
33+
}));
34+
35+
if (!isPositioned) {
36+
setIsPositioned(true);
37+
}
38+
}, [target, isPositioned]);
39+
40+
useEffect(() => {
41+
if (!target) return;
42+
43+
const initialPosition = () => {
44+
updatePosition();
45+
requestAnimationFrame(updatePosition);
46+
};
47+
const timer = setTimeout(initialPosition, 0);
48+
2349
const throttledUpdatePosition = throttle(updatePosition, throttleDelay);
2450
const scrollContainer = scrollContainerId ? document.getElementById(scrollContainerId) : null;
2551

26-
scrollContainer && scrollContainer.addEventListener('scroll', throttledUpdatePosition);
27-
window.addEventListener('resize', updatePosition);
52+
scrollContainer?.addEventListener('scroll', throttledUpdatePosition, { passive: true });
53+
window.addEventListener('resize', throttledUpdatePosition, { passive: true });
2854
return () => {
29-
window.removeEventListener('resize', updatePosition);
30-
scrollContainer && scrollContainer.removeEventListener('scroll', throttledUpdatePosition);
55+
clearTimeout(timer);
56+
window.removeEventListener('resize', throttledUpdatePosition);
57+
scrollContainer?.removeEventListener('scroll', throttledUpdatePosition);
3158
};
32-
}, [target, containerRef, scrollContainerId, throttleDelay]);
59+
}, [target, scrollContainerId, throttleDelay, updatePosition]);
60+
61+
if (!target) return null;
3362

3463
return ReactDOM.createPortal(
3564
<div
3665
className='dtable-color-picker-portal'
3766
style={{
38-
position: 'absolute',
39-
zIndex: '10',
67+
position: 'fixed',
68+
zIndex: '1049',
4069
left: position.left,
4170
top: position.top,
4271
width: '240px',
43-
height: '370px'
72+
height: '370px',
73+
visibility: position.visibility,
74+
opacity: isPositioned ? 1 : 0,
75+
transition: 'opacity 0.15s ease-in-out',
4476
}}
4577
ref={containerRef}
4678
>

0 commit comments

Comments
 (0)