/** * TrackInsertionZone - Зоны для создания новых треков * * Компонент создает drop-зоны между треками для автоматического * создания новых треков при перетаскивании медиа файлов: * - Зоны вставки выше, между и ниже треков * - Автоматическое определение типа трека по медиа файлу * - Визуальная обратная связь при hovering */ import { useDroppable } from "@dnd-kit/core" import { Plus } from "lucide-react" import { cn } from "@/lib/utils" interface TrackInsertionZoneProps { position: "above" | "between" | "below" trackId?: string // ID трека, относительно которого позиционируется зона insertIndex: number // Индекс позиции для вставки нового трека className?: string } export function TrackInsertionZone({ position, trackId, insertIndex, className }: TrackInsertionZoneProps) { const dropId = `track-insertion-${position}-${trackId || "none"}-${insertIndex}` const { isOver, setNodeRef } = useDroppable({ id: dropId, data: { type: "track-insertion", position, trackId, insertIndex, }, }) return (
{/* Индикатор вставки - показывается только при hover или drag over */}
{position === "above" && "Создать трек выше"} {position === "between" && "Создать трек между"} {position === "below" && "Создать трек ниже"}
{/* Скрытая линия разделения для визуального позиционирования */}
) } /** * TrackInsertionZones - Контейнер для управления всеми зонами вставки * * Размещает зоны вставки в правильных позициях относительно существующих треков */ interface TrackInsertionZonesProps { trackIds: string[] className?: string isVisible?: boolean // Показывать зоны только во время drag операции } export function TrackInsertionZones({ trackIds, className, isVisible = true }: TrackInsertionZonesProps) { // Не показываем зоны если они не видимы или нет треков if (!isVisible) { return null } return (
{/* Зона выше первого трека */}
{/* Зоны между треками */} {trackIds.map((trackId, index) => (
))} {/* Зона ниже последнего трека */}
) }