diff --git a/client/src/components/DraggableContainer.tsx b/client/src/components/DraggableContainer.tsx index 9333b30..b4eb1d8 100644 --- a/client/src/components/DraggableContainer.tsx +++ b/client/src/components/DraggableContainer.tsx @@ -7,6 +7,7 @@ export interface Position { left?: number | string; right?: number | string; bottom?: number | string; + transform?: string; } export type Corner = "top-left" | "top-right" | "bottom-left" | "bottom-right"; @@ -20,6 +21,10 @@ interface DraggableContainerProps { autoAlign?: boolean; /** Ограничить перетаскивание границами окна (по умолчанию false) */ constrainToBounds?: boolean; + /** Центрировать контейнер по вертикали (имеет приоритет над initialCorner и initialPosition) */ + centerVertical?: boolean; + /** Центрировать контейнер по горизонтали (имеет приоритет над initialCorner и initialPosition) */ + centerHorizontal?: boolean; /** Начальный угол экрана (имеет приоритет над initialPosition) */ initialCorner?: Corner; /** Начальная позиция контейнера (используется если не указан initialCorner) */ @@ -47,6 +52,24 @@ interface DraggableContainerProps { * * * @example + * // Размещение по центру экрана (вертикально и горизонтально) + * + * + * + * + * @example + * // Центрирование только по вертикали + * + * + * + * + * @example + * // Центрирование только по горизонтали + * + * + * + * + * @example * // С указанием начального угла и отступами в процентах * * @@ -75,6 +98,8 @@ export default function DraggableContainer({ enableSnapping = false, autoAlign = false, constrainToBounds = false, + centerVertical = false, + centerHorizontal = false, initialCorner, initialPosition, padding = "20px", @@ -105,6 +130,32 @@ export default function DraggableContainer({ // Определяем начальную позицию const getInitialPosition = (): Position => { + // Если используется центрирование + if (centerVertical || centerHorizontal) { + const position: Position = {}; + const transforms: string[] = []; + + if (centerVertical) { + position.top = "50%"; + transforms.push("translateY(-50%)"); + } else { + position.top = padding; + } + + if (centerHorizontal) { + position.left = "50%"; + transforms.push("translateX(-50%)"); + } else { + position.left = padding; + } + + if (transforms.length > 0) { + position.transform = transforms.join(" "); + } + + return position; + } + if (initialCorner) { return getPositionFromCorner(initialCorner); } @@ -112,7 +163,7 @@ export default function DraggableContainer({ return initialPosition; } // По умолчанию - верхний правый угол - return { top: padding, right: padding }; + return { top: padding, left: padding }; }; const [position, setPosition] = useState(getInitialPosition()); @@ -173,6 +224,14 @@ export default function DraggableContainer({ setDragStartAlignment(getAlignmentClassesFromPosition(position)); } + // Если контейнер был по центру с transform, убираем transform и используем абсолютную позицию + if (position.transform) { + setPosition({ + top: rect.top, + left: rect.left, + }); + } + dragRef.current = { isDragging: true, startX: clientX, @@ -329,7 +388,9 @@ export default function DraggableContainer({ if (position.top !== undefined) style.top = formatValue(position.top); if (position.left !== undefined) style.left = formatValue(position.left); if (position.right !== undefined) style.right = formatValue(position.right); - if (position.bottom !== undefined) style.bottom = formatValue(position.bottom); + if (position.bottom !== undefined) + style.bottom = formatValue(position.bottom); + if (position.transform !== undefined) style.transform = position.transform; return style; }; diff --git a/client/src/components/popups/ChatPopup.tsx b/client/src/components/popups/ChatPopup.tsx index cc0ba1a..ca32de4 100644 --- a/client/src/components/popups/ChatPopup.tsx +++ b/client/src/components/popups/ChatPopup.tsx @@ -4,6 +4,7 @@ import Button from "../ui/Button"; import { useMe } from "../../hooks/useAuth"; import clsx from "clsx"; import PopupWrapper from "../PopupWrapper"; +import DraggableContainer from "../DraggableContainer"; export default function ChatPopup() { const [messages, setMessages] = useState([ @@ -32,12 +33,14 @@ export default function ChatPopup() { } return ( - -
- - -
-
+ + +
+ + +
+
+
); } @@ -108,13 +111,13 @@ function MessageItem({ senderId, timestamp, content }: MessageItemProps) { )}
{content}
- {timestamp} + {timestamp}
user