refactor: better handle animations for tooltips

This commit is contained in:
Tim 2023-10-25 13:01:09 +02:00
parent aa4dcb7410
commit ab6a61acc2
3 changed files with 38 additions and 41 deletions

View file

@ -129,7 +129,11 @@ html {
border-radius: var(--border-radius);
background-color: var(--modal-background-color);
box-shadow: var(--outer-glow);
transition: opacity 0.25s ease-out;
transition: opacity 0.1s ease-out;
&:global(.active) {
transition-delay: 0.25s;
}
}
.router {

View file

@ -7,52 +7,47 @@ const styles = require('./styles');
const TooltipItem = React.memo(({ className, active, label, position, margin, parent }) => {
const ref = React.useRef(null);
const timeout = React.useRef(null);
const [style, setStyle] = React.useState({});
const [style, setStyle] = React.useState(null);
const onTransitionEnd = React.useCallback(() => {
if (!active) {
setStyle(null);
}
}, [active]);
React.useEffect(() => {
clearTimeout(timeout.current);
if (!ref.current) return setStyle(null);
timeout.current = setTimeout(() => {
if (active && ref.current) {
const tooltipBounds = ref.current.getBoundingClientRect();
const parentBounds = parent.getBoundingClientRect();
const tooltipBounds = ref.current.getBoundingClientRect();
const parentBounds = parent.getBoundingClientRect();
switch (position) {
case 'top':
return setStyle({
top: `${parentBounds.top - tooltipBounds.height - margin}px`,
left: `${(parentBounds.left + (parentBounds.width / 2)) - (tooltipBounds.width / 2)}px`,
});
case 'bottom':
return setStyle({
top: `${parentBounds.top + parentBounds.height + margin}px`,
left: `${(parentBounds.left + (parentBounds.width / 2)) - (tooltipBounds.width / 2)}px`,
});
case 'left':
return setStyle({
top: `${parentBounds.top + (parentBounds.height / 2) - (tooltipBounds.height / 2)}px`,
left: `${(parentBounds.left - tooltipBounds.width - margin)}px`,
});
case 'right':
return setStyle({
top: `${parentBounds.top + (parentBounds.height / 2) - (tooltipBounds.height / 2)}px`,
left: `${(parentBounds.left + parentBounds.width + margin)}px`,
});
}
}
});
return () => clearTimeout(timeout.current);
switch (position) {
case 'top':
return setStyle({
top: `${parentBounds.top - tooltipBounds.height - margin}px`,
left: `${(parentBounds.left + (parentBounds.width / 2)) - (tooltipBounds.width / 2)}px`,
});
case 'bottom':
return setStyle({
top: `${parentBounds.top + parentBounds.height + margin}px`,
left: `${(parentBounds.left + (parentBounds.width / 2)) - (tooltipBounds.width / 2)}px`,
});
case 'left':
return setStyle({
top: `${parentBounds.top + (parentBounds.height / 2) - (tooltipBounds.height / 2)}px`,
left: `${(parentBounds.left - tooltipBounds.width - margin)}px`,
});
case 'right':
return setStyle({
top: `${parentBounds.top + (parentBounds.height / 2) - (tooltipBounds.height / 2)}px`,
left: `${(parentBounds.left + parentBounds.width + margin)}px`,
});
}
}, [active, position, margin, parent, label]);
return (
<div
ref={ref}
className={classNames(className, styles['tooltip-item'], { 'active': active })}
style={style}
>
<div ref={ref} className={classNames(className, styles['tooltip-item'], { 'active': active })} style={style} onTransitionEnd={onTransitionEnd}>
{ label }
</div>
);

View file

@ -2,11 +2,9 @@
.tooltip-item {
position: fixed;
visibility: hidden;
opacity: 0;
&:global(.active) {
visibility: visible;
opacity: 1;
}
}