From 3f463b8ff390cd4b48facee50439c002e079f769 Mon Sep 17 00:00:00 2001 From: inmake Date: Tue, 21 Oct 2025 20:28:30 +0500 Subject: [PATCH] Enhance DraggableContainer with new props for enabling/disabling functionality and dragging. Update Popup components to improve structure and responsiveness, removing unnecessary draggable props. Integrate console logging for debugging in PopupContainer and ControlsPopover. --- client/src/components/DraggableContainer.tsx | 52 ++++++++++++++++++-- client/src/components/PopupContainer.tsx | 8 ++- client/src/components/PopupHeader.tsx | 13 ++--- client/src/components/PopupWrapper.tsx | 10 +--- client/src/components/popups/ChatPopup.tsx | 9 +++- client/src/components/ui/ControlsPopover.tsx | 17 +++++-- client/src/pages/NewSessionPage.tsx | 1 + 7 files changed, 80 insertions(+), 30 deletions(-) diff --git a/client/src/components/DraggableContainer.tsx b/client/src/components/DraggableContainer.tsx index 0f77e68..d76d295 100644 --- a/client/src/components/DraggableContainer.tsx +++ b/client/src/components/DraggableContainer.tsx @@ -15,6 +15,10 @@ export type Corner = "top-left" | "top-right" | "bottom-left" | "bottom-right"; interface DraggableContainerProps { /** Содержимое контейнера */ children: ReactNode; + /** Включить весь функционал компонента (по умолчанию true). Если false, компонент просто рендерит children без стилей и позиционирования */ + enabled?: boolean; + /** Включить возможность перетаскивания (по умолчанию true) */ + draggable?: boolean; /** Включить снэпинг к ближайшей четверти экрана при отпускании (по умолчанию true) */ enableSnapping?: boolean; /** Автоматическое flex-выравнивание в зависимости от прижатого угла (по умолчанию false) */ @@ -70,6 +74,24 @@ interface DraggableContainerProps { * * * @example + * // Центрирование по вертикали с указанием позиции справа + * + * + * + * + * @example + * // Отключение перетаскивания (статичный контейнер) + * + * + * + * + * @example + * // Полное отключение функционала (компонент не применяет никаких стилей) + * + * + * + * + * @example * // С указанием начального угла и отступами в процентах * * @@ -95,6 +117,8 @@ interface DraggableContainerProps { */ export default function DraggableContainer({ children, + enabled = true, + draggable = true, enableSnapping = false, autoAlign = false, constrainToBounds = false, @@ -102,7 +126,7 @@ export default function DraggableContainer({ centerHorizontal = false, initialCorner, initialPosition, - padding = "16px", + padding = "1.111vw", className = "", onPositionChange, }: DraggableContainerProps) { @@ -135,16 +159,26 @@ export default function DraggableContainer({ const position: Position = {}; const transforms: string[] = []; + // Вертикальное позиционирование if (centerVertical) { position.top = "50%"; transforms.push("translateY(-50%)"); + } else if (initialPosition?.top !== undefined) { + position.top = initialPosition.top; + } else if (initialPosition?.bottom !== undefined) { + position.bottom = initialPosition.bottom; } else { position.top = padding; } + // Горизонтальное позиционирование if (centerHorizontal) { position.left = "50%"; transforms.push("translateX(-50%)"); + } else if (initialPosition?.left !== undefined) { + position.left = initialPosition.left; + } else if (initialPosition?.right !== undefined) { + position.right = initialPosition.right; } else { position.left = padding; } @@ -246,10 +280,12 @@ export default function DraggableContainer({ }; const handleMouseDown = (e: React.MouseEvent) => { + if (!draggable) return; startDrag(e.clientX, e.clientY); }; const handleTouchStart = (e: React.TouchEvent) => { + if (!draggable) return; if (e.touches.length > 0) { startDrag(e.touches[0].clientX, e.touches[0].clientY); } @@ -407,19 +443,25 @@ export default function DraggableContainer({ return getAlignmentClassesFromPosition(position); }; + // Если компонент отключен, просто рендерим children без стилей и логики + if (!enabled) { + return <>{children}; + } + return (
{children}
diff --git a/client/src/components/PopupContainer.tsx b/client/src/components/PopupContainer.tsx index e033e70..fe46d6b 100644 --- a/client/src/components/PopupContainer.tsx +++ b/client/src/components/PopupContainer.tsx @@ -1,19 +1,25 @@ import { AnimatePresence, motion } from "motion/react"; import usePopupStore from "../store/popupStore"; +import { useEffect } from "react"; function PopupContainer() { const { popup } = usePopupStore(); const isMobile = innerWidth < 640; + useEffect(() => { + console.log(popup); + }, [popup]); + return ( {popup && ( {popup} diff --git a/client/src/components/PopupHeader.tsx b/client/src/components/PopupHeader.tsx index ed5455b..c4321ed 100644 --- a/client/src/components/PopupHeader.tsx +++ b/client/src/components/PopupHeader.tsx @@ -1,4 +1,3 @@ -import clsx from "clsx"; import usePopupStore from "../store/popupStore"; import XMarkIcon from "./icons/XMarkIcon"; import Button from "./ui/Button"; @@ -6,22 +5,16 @@ import Button from "./ui/Button"; interface PopupHeaderProps { title?: string; leftButton?: React.ReactNode; - draggable?: boolean; } -function PopupHeader({ title, leftButton, draggable }: PopupHeaderProps) { +function PopupHeader({ title, leftButton }: PopupHeaderProps) { const { setPopup } = usePopupStore(); return ( -
+
{leftButton}
{title && ( -

{title}

+

{title}

)}