{"version":3,"sources":["../src/components/PanelGrid.tsx","../src/components/PanelGrid.module.css","../src/utils/utils.ts","../src/utils/calculateUtils.ts"],"sourcesContent":["import React, { cloneElement, isValidElement, useMemo, useRef, useState } from 'react';\nimport type { JSX } from 'react';\nimport styles from './PanelGrid.module.css';\nimport { calculateContainerHeight, calculatePanelStyle, getDropPosition, resolveCollisions } from '../utils/calculateUtils';\nimport type { Panel } from '../types/types';\nimport { isColliding } from '../utils/utils';\n\ninterface PanelGridProps {\n  /** \n   * 렌더링할 패널 배열 \n   * 각 패널은 위치(x, y), 크기(w, h), 고유 id 등을 포함함\n   */\n  panels?: Panel[];\n\n  /** \n   * 한 줄에 배치할 컬럼 수 \n   * 기본값은 12\n   */\n  cols?: number;\n\n  /** \n   * 한 grid row 당 높이 (px 단위) \n   * 패널 높이 계산에 사용됨 \n   */\n  rowHeight?: number;\n\n  /** \n   * 전체 grid 컨테이너의 너비 (px 단위) \n   */\n  width?: number;\n\n  /** \n   * 각 패널 사이의 간격: [수평(px), 수직(px)] \n   * 기본값은 [0, 0]\n   */\n  margin?: [number, number];\n\n  /** \n   * grid 컨테이너의 안쪽 여백: [좌우(px), 상하(px)] \n   * 기본값은 [0, 0]\n   */\n  padding?: [number, number];\n  \n  /**\n   * 드래그 앤 드롭 기능 활성화 여부\n   * 기본값은 true\n   */\n  isDraggable?: boolean;\n\n  /**\n   * 드래그 앤 드롭 시 패널 간 충돌 방지 여부\n   * 기본값은 true\n   */\n  preventCollision?: boolean;\n\n  /**\n   * 패널 위치가 변경될 때 호출되는 콜백 함수\n   */\n  onLayoutChange?: (layout: Panel[]) => void;\n\n  /** \n   * 각 패널에 대응되는 자식 React 요소들 \n   */\n  children?: React.ReactNode;\n}\n\ninterface GridChildProps extends React.HTMLAttributes<HTMLDivElement> {\n  /** \n   * 외부에서 전달할 style 속성 (override 가능)\n   */\n  style?: React.CSSProperties;\n\n  /** \n   * 클래스명을 문자열 형태로 전달\n   */\n  className?: string;\n\n  /** \n   * 테스트 용도의 식별자 (data-testid)\n   */\n  'data-testid'?: string;\n};\n\n/**\n * PanelGrid는 주어진 패널 데이터를 기반으로 고정된 컬럼 수와 행 높이에 따라\n * 격자 형태로 자식 컴포넌트를 배치하고, 드래그 앤 드롭을 통해 순서를 재배치할 수 있는 컴포넌트입니다.\n */\nconst PanelGrid = ({\n  panels = [],\n  cols = 12,\n  rowHeight = 50,\n  width = 1200,\n  margin = [0, 0],\n  padding = [0, 0],\n  isDraggable = true,\n  preventCollision = true,\n  onLayoutChange,\n  children,\n}: PanelGridProps): JSX.Element => {\n  const [panelList, setPanelList] = useState<Panel[]>(panels);\n  const dragItem = useRef<Panel | null>(null);\n  const containerRef = useRef<HTMLDivElement>(null);\n  const originalPanels = useRef<Panel[]>(panels);\n  const lastDragOverPosRef = useRef<{ x: number; y: number } | null>(null);\n\n  const [dragOverPosition, setDragOverPosition] = useState<{\n    x: number;\n    y: number;\n    w: number;\n    h: number;\n  } | null>(null);\n\n  const unitWidth = width / cols;\n  const containerHeight = calculateContainerHeight({\n    panels: panelList,\n    rowHeight,\n    marginY: margin[1],\n    paddingY: padding[1],\n  });\n  const childrenArray = useMemo(() => React.Children.toArray(children), [children]);\n\n\n  /**\n   * 드래그 시작 시 호출되는 함수\n   */\n  const handleDragStart = (panel: Panel) => {\n    dragItem.current = panel;\n    originalPanels.current = panelList.map(p => ({ ...p }));\n  };\n\n  /**\n   * 드래그가 지속되는 동안 호출되는 함수\n   */\n  const handleDrag = (event: React.DragEvent<HTMLDivElement>) => {\n    event.preventDefault();\n    if (dragItem.current === null || !containerRef.current) return;\n\n    const draggedPanel = dragItem.current;\n    const { w = 1, h = 1 } = draggedPanel;\n\n    const containerRect = containerRef.current.getBoundingClientRect();\n    const maxRows = Math.floor(containerHeight / rowHeight);\n\n    if (event.clientX === 0 && event.clientY === 0) return;\n\n    const { x, y } = getDropPosition({\n      event,\n      config: {\n        containerRect,\n        unitWidth,\n        rowHeight,\n        padding,\n        margin,\n        cols,\n        maxRows,\n        panelSize: { w, h },\n      },\n    });\n\n    const last = lastDragOverPosRef.current;\n    if (last && last.x === x && last.y === y) return;\n\n    lastDragOverPosRef.current = { x, y };\n    setDragOverPosition({ x, y, w, h });\n\n    const tempDragged = { ...draggedPanel, x, y };\n    const isOverlap = panelList.some(\n      (panel) => panel.id !== draggedPanel.id && isColliding(tempDragged, panel)\n    );\n\n    let nextList = originalPanels.current.map((p) => ({ ...p }));\n    if (preventCollision && isOverlap) {\n      nextList = resolveCollisions(tempDragged, panelList);\n    }\n\n    const hasChanged = nextList.some((panel, i) => {\n      const prev = panelList[i];\n      return (\n        panel.x !== prev.x ||\n        panel.y !== prev.y ||\n        panel.w !== prev.w ||\n        panel.h !== prev.h\n      );\n    });\n\n    if (hasChanged) {\n      setPanelList(nextList);\n    }\n  };\n\n  /**\n   * 드래그가 종료되었을 때 호출되는 함수\n   */\n  const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {\n    if (dragItem.current === null || !containerRef.current) return;\n\n    const draggedPanel = dragItem.current;\n    const { w = 1, h = 1 } = draggedPanel;\n\n    const containerRect = containerRef.current.getBoundingClientRect();\n    const maxRows = Math.floor(containerHeight / rowHeight);\n\n    const { x, y } = getDropPosition({\n      event,\n      config: {\n        containerRect,\n        unitWidth,\n        rowHeight,\n        padding,\n        margin,\n        cols,\n        maxRows,\n        panelSize: { w, h },\n      },\n    });\n\n    const tempDragged = { ...draggedPanel, x, y };\n    const isOverlap = panelList.some(\n      (panel) => panel.id !== draggedPanel.id && isColliding(tempDragged, panel)\n    );\n\n    let updatedPanels = panelList;\n    if (preventCollision && isOverlap) {\n      updatedPanels = resolveCollisions(tempDragged, panelList);\n    } else {\n      updatedPanels = panelList.map((panel) =>\n        panel.id === draggedPanel.id ? { ...panel, x, y } : panel\n      );\n    }\n\n    const hasChanged = updatedPanels.some((panel, i) => {\n      const prev = panelList[i];\n      return (\n        panel.x !== prev.x ||\n        panel.y !== prev.y ||\n        panel.w !== prev.w ||\n        panel.h !== prev.h\n      );\n    });\n\n    if (hasChanged) {\n      requestAnimationFrame(() => {\n        setPanelList(updatedPanels);\n        onLayoutChange?.(updatedPanels);\n        setDragOverPosition(null);\n        lastDragOverPosRef.current = null;\n      });\n    } else {\n      setDragOverPosition(null);\n      lastDragOverPosRef.current = null;\n    }\n  };\n\n  /**\n   * 드래그 중인 패널의 스타일을 계산하는 함수\n   */\n  const dropIndicatorElement = useMemo(() => {\n    if (!dragOverPosition) return null;\n\n    return (\n      <div\n        className={styles.dropIndicator}\n        style={calculatePanelStyle({\n          dimensions: dragOverPosition,\n          unitWidth,\n          rowHeight,\n          cols,\n          marginX: margin[0],\n          marginY: margin[1],\n          paddingX: padding[0],\n          paddingY: padding[1],\n        })}\n      />\n    );\n  }, [dragOverPosition, unitWidth, rowHeight, cols, margin, padding]);\n\n\n  /**\n   * 자식 요소들을 스타일링하여 반환하는 함수\n   */\n  const styledChildren = useMemo(() => {\n    return childrenArray.map((child, index) => {\n      if (!isValidElement(child)) return null;\n\n      const panel = panelList[index];\n      const style = calculatePanelStyle({\n        dimensions: {\n          x: panel?.x,\n          y: panel?.y,\n          w: panel?.w,\n          h: panel?.h,\n        },\n        unitWidth,\n        rowHeight,\n        cols,\n        marginX: margin[0],\n        marginY: margin[1],\n        paddingX: padding[0],\n        paddingY: padding[1],\n      });\n\n      const element = child as React.ReactElement<GridChildProps>;\n\n      return cloneElement(element, {\n        'data-testid': 'grid-panel',\n        key: panel?.id || `default-key-${index}`,\n        style: { ...style, ...(element.props.style || {}) },\n        className: [styles.gridItemPanel, element.props.className]\n        .filter(Boolean)\n        .join(' '),\n        draggable: isDraggable !== false,\n        onDragStart: isDraggable !== false ? () => handleDragStart(panel) : undefined,\n        onDrag: isDraggable !== false ? handleDrag : undefined,\n        onDragEnd: isDraggable !== false ? handleDrop : undefined,\n      });\n    });\n  }, [\n    childrenArray,\n    panelList,\n    unitWidth,\n    rowHeight,\n    cols,\n    margin,\n    padding,\n  ]);\n\n\n  return (\n    <div\n      ref={containerRef}\n      style={{ height: containerHeight, width }}\n      className={styles.gridContainer}\n      data-testid=\"grid-container\"\n    >\n      {dropIndicatorElement}\n      {styledChildren}\n    </div>\n  );\n};\n\nexport default PanelGrid;",".gridContainer {\n  position: relative;\n}\n\n.gridItemPanel {\n  position: absolute;\n}\n\n.dropIndicator {\n  position: absolute;\n  background-color: rgba(0, 128, 255, 0.2);\n  border: 2px dashed #007aff;\n  border-radius: 6px;\n  pointer-events: none;\n  z-index: 999;\n}","import { Panel } from \"../types/types\";\n\n/**\n * container 내부로만 배치되도록 제한 (좌표 제한)\n * @return container 내부 좌표 최대값을 넘어갈 경우 최대값으로 반환\n */\nexport function clamp(value: number, min: number, max: number): number {\n  return Math.max(min, Math.min(max, value));\n};\n\n/**\n * 두 패널이 겹치는지 여부를 반환합니다.\n * @returns true = 겹침, false = 겹치지 않음\n */\nexport function isColliding(panel1: Panel, panel2: Panel): boolean {\n  const a = { x: 0, y: 0, w: 0, h: 0, ...panel1 };\n  const b = { x: 0, y: 0, w: 0, h: 0, ...panel2 };\n\n  return !(\n    a.x + a.w <= b.x ||\n    a.x >= b.x + b.w ||\n    a.y + a.h <= b.y ||\n    a.y >= b.y + b.h\n  );\n};","import { Panel } from \"../types/types\";\nimport { clamp, isColliding } from \"./utils\";\n\ntype Dimension = Pick<Panel, 'w' | 'h' | 'x' | 'y'>;\ninterface CalculatePanelStyleProps {\n  /** 패널의 위치와 크기 정보 (x, y, w, h) */\n  dimensions: Dimension;\n  /** 1 grid column 당 픽셀 너비 */\n  unitWidth: number;\n  /** 1 grid row 당 픽셀 높이 */\n  rowHeight: number;\n\n  /** grid 컬럼 수 (x 범위 제한에 사용) - 기본값: 12*/\n  cols?: number;\n\n  /**\n   * 각 grid column 사이의 수평 margin(px) — 기본값: 0  \n   * → x축 방향으로 패널 간 간격을 두고 싶을 때 사용\n   */\n  marginX?: number;\n\n  /**\n   * 각 grid row 사이의 수직 margin(px) — 기본값: 0 \n   * → y축 방향으로 패널 간 간격을 두고 싶을 때 사용\n   */\n  marginY?: number;\n\n  /**\n   * 전체 grid의 왼쪽 padding(px) — 기본값: 0  \n   * → 전체 컨테이너에서 좌측 여백을 지정할 때 사용\n   */\n  paddingX?: number;\n\n  /**\n   * 전체 grid의 상단 padding(px) — 기본값: 0  \n   * → 전체 컨테이너에서 상단 여백을 지정할 때 사용\n   */\n  paddingY?: number;\n}\ninterface CalculateContainerHeightProps {\n  /** 렌더링할 패널 배열 */\n  panels: Panel[];\n\n  /** 한 row의 픽셀 높이 */\n  rowHeight: number;\n\n  /** 각 row 간의 수직 마진 (px) */\n  marginY?: number;\n\n  /** 컨테이너의 상하 padding 값 (px) */\n  paddingY?: number;\n}\ninterface DropPositionConfig {\n  /**\n   * grid 컨테이너의 DOM 좌표 (client 기준 좌상단 좌표와 너비/높이 정보 포함)\n   * → 마우스 위치를 grid 내부 좌표로 환산하기 위해 필요\n   */\n  containerRect: DOMRect;\n\n  /**\n   * 1 grid column의 너비 (px)\n   * → 마우스 위치를 컬럼 단위로 환산할 때 사용\n   */\n  unitWidth: number;\n\n  /**\n   * 1 grid row의 높이 (px)\n   * → 마우스 위치를 row 단위로 환산할 때 사용\n   */\n  rowHeight: number;\n\n  /**\n   * [왼쪽 padding, 위쪽 padding] (px)\n   * → 전체 grid의 바깥쪽 여백 (container 기준 내부 시작 위치 보정용)\n   */\n  padding: [number, number];\n\n  /**\n   * [컬럼 간 간격, 행 간 간격] (px)\n   * → 각 grid 요소 사이의 간격 (패널 사이 여백 포함)\n   */\n  margin: [number, number];\n\n  /**\n   * grid의 총 컬럼 수\n   * → 배치 가능한 x 범위를 제한하는데 사용\n   */\n  cols: number;\n\n  /**\n   * grid에서 배치 가능한 최대 row 수\n   * → 배치 가능한 y 범위를 제한하는데 사용\n   */\n  maxRows: number;\n\n  /**\n   * 드래그 중인 패널의 크기 (w: 너비 컬럼 수, h: 높이 row 수)\n   * → 현재 좌표가 이 panel을 담을 수 있는 공간인지 판단하기 위해 필요\n   */\n  panelSize: {\n    w: number;\n    h: number;\n  };\n}\ninterface DropPositionInput {\n  /**\n   * 드래그 종료 시 전달되는 마우스 이벤트 (clientX, clientY 좌표 포함)\n   */\n  event: React.DragEvent<HTMLDivElement>;\n\n  /**\n   * 위치 계산에 필요한 컨텍스트 정보\n   */\n  config: DropPositionConfig;\n}\n\n\n/**\n * 개별 패널의 style 객체를 계산하는 함수\n *\n * @returns React에서 사용할 수 있는 객체\n */\nexport function calculatePanelStyle({\n  dimensions: { x = 0, y = 0, w = 1, h = 1 },\n  unitWidth,\n  rowHeight,\n  cols = 12,\n  marginX = 0,\n  marginY = 0,\n  paddingX = 0,\n  paddingY = 0,\n}: CalculatePanelStyleProps) {\n  const clampedX = Math.min(x, cols - w);\n\n  const left = clampedX * (unitWidth + marginX) + paddingX;\n  const top = y * (rowHeight + marginY) + paddingY;\n  const width = unitWidth * w + marginX * (w - 1);\n  const height = rowHeight * h + marginY * (h - 1);\n\n  return {\n    transform: `translate(${left}px, ${top}px)`,\n    width,\n    height\n  };\n}\n\n/**\n * 전체 grid container의 높이를 계산하는 함수\n * 모든 패널의 y+h 중 최댓값을 기준으로 계산합니다.\n *\n * @returns 컨테이너 전체 높이 (px 단위)\n */\nexport function calculateContainerHeight({\n  panels,\n  rowHeight,\n  marginY = 0,\n  paddingY = 0,\n}: CalculateContainerHeightProps): number {\n  if (panels.length === 0) return 0;\n  const maxY = Math.max(...panels.map(p => (p?.y || 0) + (p?.h || 1)));\n\n  return (\n    maxY * rowHeight +\n    (maxY - 1) * marginY +\n    paddingY * 2\n  );\n};\n\n\n/**\n * 마우스 좌표를 기반으로 grid 좌표를 계산합니다.\n * @returns grid 상의 x, y 좌표\n */\nexport function getDropPosition({\n  event,\n  config: {\n    containerRect,\n    unitWidth,\n    rowHeight,\n    padding,\n    margin,\n    cols,\n    maxRows,\n    panelSize,\n  },\n}: DropPositionInput): { x: number; y: number } {\n  const mouseLeft = event.clientX - containerRect.left;\n  const mouseTop = event.clientY - containerRect.top;\n\n  const panelWidth = unitWidth * panelSize.w + margin[0] * (panelSize.w - 1);\n  const panelHeight = rowHeight * panelSize.h + margin[1] * (panelSize.h - 1);\n\n  const adjustedLeft = mouseLeft - padding[0] - panelWidth / 2;\n  const adjustedTop = mouseTop - padding[1] - panelHeight / 2;\n\n  const newX = Math.round(adjustedLeft / (unitWidth + margin[0]));\n  const newY = Math.round(adjustedTop / (rowHeight + margin[1]));\n\n  const maxX = cols - panelSize.w;\n  const maxY = maxRows - panelSize.h;\n\n  return {\n    x: clamp(newX, 0, maxX),\n    y: clamp(newY, 0, maxY),\n  };\n}\n\n/**\n * 드롭된 패널을 해당 위치에 고정시키고,\n * 충돌하는 다른 패널들을 재귀적으로 아래로 밀어주는 함수\n * \n * @param draggedPanel 드롭 위치가 적용된 이동된 패널\n * @param panels 기존 패널 배열 (draggedPanel 포함)\n * @returns 충돌이 해결된 새로운 패널 배열\n */\nexport function resolveCollisions(\n  draggedPanel: Panel,\n  panels: Panel[]\n): Panel[] {\n  const newPanels = panels.map(p =>\n    p.id === draggedPanel.id ? draggedPanel : { ...p }\n  );\n\n  const visited = new Set<string>();\n\n  function pushDown(panel: Panel) {\n    if (!panel.id) return;\n    if (visited.has(panel.id)) return;\n    visited.add(panel.id);\n\n    for (const other of newPanels) {\n      if (panel.id === other.id) continue;\n\n      if (isColliding(panel, other)) {\n        // 겹치는 패널을 아래로 한 칸 밀기\n        other.y = (panel.y || 0) + (panel.h || 1);\n        pushDown(other); // 재귀적으로 처리\n      }\n    }\n  }\n\n  pushDown(draggedPanel);\n\n  return newPanels;\n}"],"mappings":"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","names":["PanelGrid_default"]}