/** * Sortable wrapper for a project (space) sidebar group card. * Accepts an optional `handleSlot` so the parent can render a grip handle * inside its own title row — this keeps the handle positioned correctly * relative to the label. */ import { CSS } from "@dnd-kit/utilities"; import { useSortable } from "@dnd-kit/sortable"; import { memo, useMemo } from "react"; interface SortableGroupProps { group: { spaceId: string; key: string; title?: string | null }; /** When provided, rendered alongside children inside the drag node. */ handleSlot?: React.ReactNode; children: React.ReactNode; } export const SortableGroup = memo(function SortableGroup({ group, handleSlot, children, }: SortableGroupProps) { const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: group.spaceId, }); const style: React.CSSProperties = useMemo( () => ({ transform: CSS.Translate.toString(transform), transition, opacity: isDragging ? 0.5 : undefined, zIndex: isDragging ? 1000 : undefined, }), [transform, transition, isDragging], ); return (
{handleSlot} {children}
); });