This commit is contained in:
2025-10-23 12:23:03 +05:00
parent e78c1d892e
commit fb2d9258ac
3 changed files with 42 additions and 8 deletions
+15 -6
View File
@@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from "react";
import { flushSync } from "react-dom";
import type { ReactNode } from "react";
import clsx from "clsx";
@@ -282,11 +283,19 @@ export default function DraggableContainer({
setDragStartAlignment(getAlignmentClassesFromPosition(position));
}
// Если контейнер был по центру с transform, убираем transform и используем абсолютную позицию
if (position.transform) {
setPosition({
top: rect.top,
left: rect.left,
// Конвертируем позицию в left/top перед началом драга
// Это нужно чтобы избежать скачка при переходе с right/bottom на left/top
// Используем flushSync для синхронного обновления DOM
if (
position.transform ||
position.right !== undefined ||
position.bottom !== undefined
) {
flushSync(() => {
setPosition({
top: rect.top,
left: rect.left,
});
});
}
@@ -496,7 +505,7 @@ export default function DraggableContainer({
className={clsx(
"pointer-events-auto",
// draggable && "touch-none",
!isDragging && "transition-all duration-500 ease-out",
!isDragging && enableSnapping && "transition-all duration-500 ease-out",
draggable &&
!dragHandleRef &&
(isDragging ? "cursor-grabbing" : "cursor-grab"),
+25 -2
View File
@@ -1,4 +1,5 @@
import { useEffect, useState } from "react";
import { createPortal } from "react-dom";
import { AnimatePresence, motion } from "motion/react";
import clsx from "clsx";
@@ -19,6 +20,7 @@ function PopoverWrapper({
}: PopoverProps) {
const [openUpwards, setOpenUpwards] = useState(false);
const [menuHeight, setMenuHeight] = useState(0);
const [, forceUpdate] = useState(0);
useEffect(() => {
if (
@@ -33,6 +35,26 @@ function PopoverWrapper({
}
}, [parentElRef, isOpened, menuHeight, position]);
// Обновляем позицию при изменении положения родительского элемента
useEffect(() => {
if (!isOpened) return;
let animationFrameId: number;
const updatePosition = () => {
forceUpdate((prev) => prev + 1);
animationFrameId = requestAnimationFrame(updatePosition);
};
animationFrameId = requestAnimationFrame(updatePosition);
return () => {
if (animationFrameId) {
cancelAnimationFrame(animationFrameId);
}
};
}, [isOpened]);
const getPositionStyles = () => {
if (!parentElRef.current) return {};
@@ -66,7 +88,7 @@ function PopoverWrapper({
};
};
return (
return createPortal(
<AnimatePresence>
{isOpened && (
<motion.div
@@ -87,7 +109,8 @@ function PopoverWrapper({
<div className="2xl:p-[0.278vw] p-1">{children}</div>
</motion.div>
)}
</AnimatePresence>
</AnimatePresence>,
document.body
);
}
+2
View File
@@ -11,6 +11,7 @@ import ChatPopup from "../components/popups/ChatPopup";
import ChatFilledIcon from "../components/icons/ChatFilledIcon";
import ParticipantsPopup from "../components/popups/ParticipantsPopup";
import ControlsPopover from "../components/ui/ControlsPopover";
import SessionUsersPanel2 from "../components/SessionUsersPanel2";
function HomePage() {
const { data: user } = useMe();
@@ -59,6 +60,7 @@ function HomePage() {
</div>
</FloatingActionButton>
<ControlsPopover />
<SessionUsersPanel2 />
<div className="space-y-4">
<div className="p-4 bg-blue-50 rounded-lg border border-blue-200">