{"version":3,"file":"JSplitter.vue2.cjs","sources":["../../../../src/components/atoms/JSplitter.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch, nextTick } from 'vue'\nimport { cn } from '@/lib/utils'\nimport {\n  ResizablePanelGroup,\n  ResizablePanel,\n  ResizableHandle,\n} from '@/components/shadcn/resizable'\nimport { useBreakpoint } from '@/composables/useBreakpoint'\nimport type { SplitterPanel } from 'reka-ui'\nimport type { SplitterSizes, JSplitterMethods } from '@/types/splitter.types'\n\ntype Orientation = 'horizontal' | 'vertical'\n\nconst props = withDefaults(\n  defineProps<{\n    /** 분할 방향 (horizontal: 좌우, vertical: 상하) */\n    direction?: Orientation\n    /** 첫 번째 패널의 기본 크기 (%) */\n    defaultSize?: number\n    /** 첫 번째 패널의 최소 크기 (%) */\n    minSize?: number\n    /** 첫 번째 패널의 최대 크기 (%) */\n    maxSize?: number\n    /** 두 번째 패널의 최소 크기 (%) */\n    secondMinSize?: number\n    /** 두 번째 패널의 최대 크기 (%) */\n    secondMaxSize?: number\n    /** ResizableHandle에 grip 아이콘 표시 여부 */\n    withHandle?: boolean\n    /** 패널 간 여백 (px) */\n    gap?: number\n    /** 추가 CSS 클래스 */\n    class?: string\n    /** 모바일에서 자동 수직 전환 (기본: true) */\n    responsive?: boolean\n    /** v-model:sizes - [firstSize, secondSize], 합계는 100이어야 함 */\n    sizes?: SplitterSizes\n    /** 첫 번째 패널 collapsible 여부 */\n    collapsibleFirst?: boolean\n    /** 두 번째 패널 collapsible 여부 */\n    collapsibleSecond?: boolean\n    /** collapsible 시 첫 번째 패널 축소 크기 (%) */\n    collapsedSizeFirst?: number\n    /** collapsible 시 두 번째 패널 축소 크기 (%) */\n    collapsedSizeSecond?: number\n    /** collapse/expand 시 슬라이드 애니메이션 여부 */\n    animated?: boolean\n    /** 슬라이드 애니메이션 지속 시간 (ms) */\n    animationDuration?: number\n  }>(),\n  {\n    direction: 'horizontal',\n    defaultSize: 40,\n    minSize: 20,\n    withHandle: false,\n    gap: 2,\n    responsive: true,\n    collapsibleFirst: false,\n    collapsibleSecond: false,\n    collapsedSizeFirst: 0,\n    collapsedSizeSecond: 0,\n    animated: true,\n    animationDuration: 300,\n  },\n)\n\nconst emit = defineEmits<{\n  'update:sizes': [sizes: SplitterSizes]\n  'resize': [sizes: SplitterSizes, source: 'drag' | 'api' | 'prop']\n}>()\n\nconst { isMobile } = useBreakpoint()\n\n// 모바일에서 horizontal → vertical 자동 전환\nconst effectiveDirection = computed<Orientation>(() => {\n  if (props.responsive && isMobile.value && props.direction === 'horizontal') {\n    return 'vertical'\n  }\n  return props.direction\n})\n\n// 모바일 수직 전환 시 50:50 균등 분할\nconst effectiveDefaultSize = computed(() => {\n  if (props.responsive && isMobile.value && props.direction === 'horizontal') {\n    return 50\n  }\n  return props.defaultSize\n})\n\n// 두 번째 패널의 기본 크기 계산\nconst secondDefaultSize = computed(() => 100 - effectiveDefaultSize.value)\n\n// ── Template Refs ────────────────────────────────────────────────────\nconst firstPanelRef = ref<InstanceType<typeof SplitterPanel> | null>(null)\nconst secondPanelRef = ref<InstanceType<typeof SplitterPanel> | null>(null)\n\n// ── collapse/expand 자체 상태 — reka-ui 타이밍 의존 제거 ─────────────\nconst _firstCollapsedSize = ref(0)\nconst _secondCollapsedSize = ref(0)\nconst _isFirstCollapsed = ref(false)\nconst _isSecondCollapsed = ref(false)\nconst _isAnimating = ref(false)\n\n// ── 프로그래매틱 collapse 시 min/maxSize 임시 제거 ─────────────────────\n// reka-ui에 collapsible을 전달하지 않으므로 드래그는 항상 min/maxSize를 지킴\n// collapse API 호출 시에만 제약을 임시 해제:\n//   collapseFirst → firstMin=0, secondMax=100 (두 번째 패널이 100%까지 확장 허용)\n//   collapseSecond → secondMin=0, firstMax=100 (첫 번째 패널이 100%까지 확장 허용)\nconst _minSizeFirstOverride = ref<number | undefined>(undefined)\nconst _minSizeSecondOverride = ref<number | undefined>(undefined)\nconst _maxSizeFirstOverride = ref<number | undefined>(undefined)\nconst _maxSizeSecondOverride = ref<number | undefined>(undefined)\nconst _effectiveMinSizeFirst = computed(() => _minSizeFirstOverride.value ?? props.minSize)\nconst _effectiveMinSizeSecond = computed(() => _minSizeSecondOverride.value ?? props.secondMinSize)\nconst _effectiveMaxSizeFirst = computed(() => _maxSizeFirstOverride.value ?? props.maxSize)\nconst _effectiveMaxSizeSecond = computed(() => _maxSizeSecondOverride.value ?? props.secondMaxSize)\n\n// ── 무한 루프 방지 플래그 ─────────────────────────────────────────────\n// prop→resize() 호출 중일 때 @layout 핸들러가 update:sizes를 emit하지 않도록 차단\nlet isUpdatingFromProp = false\n\n// reka-ui resize() 후 onLayout이 부동소수점 오차(~0.001)로 발화될 수 있어\n// collapsedSize와 단순 비교하면 collapse 직후 isCollapsed가 잘못 리셋됨.\n// 드래그로 진짜 열리는 경우를 구분할 수 있는 최소 임계값.\nconst COLLAPSE_OPEN_THRESHOLD = 0.5\n\n// ── @layout 핸들러 (드래그 포함 모든 크기 변경) ────────────────────────\nfunction handleLayout(layout: number[]) {\n  if (isUpdatingFromProp) return\n\n  // 드래그로 collapsed 패널이 열리면 상태 동기화 + min/maxSize 복원\n  // (부동소수점 오차 방지: collapsedSize + COLLAPSE_OPEN_THRESHOLD 초과 시에만 열린 것으로 판단)\n  if (_isFirstCollapsed.value && (layout[0] ?? 0) > props.collapsedSizeFirst + COLLAPSE_OPEN_THRESHOLD) {\n    _isFirstCollapsed.value = false\n    if ((layout[0] ?? 0) >= (props.minSize ?? 0)) {\n      _minSizeFirstOverride.value = undefined\n    }\n    _maxSizeSecondOverride.value = undefined\n  }\n  if (_isSecondCollapsed.value && (layout[1] ?? 0) > props.collapsedSizeSecond + COLLAPSE_OPEN_THRESHOLD) {\n    _isSecondCollapsed.value = false\n    if ((layout[1] ?? 0) >= (props.secondMinSize ?? 0)) {\n      _minSizeSecondOverride.value = undefined\n    }\n    _maxSizeFirstOverride.value = undefined\n  }\n\n  const sizes: SplitterSizes = [\n    Math.round((layout[0] ?? 0) * 10) / 10,\n    Math.round((layout[1] ?? 0) * 10) / 10,\n  ]\n  emit('update:sizes', sizes)\n  emit('resize', sizes, 'drag')\n}\n\n// ── sizes prop watch ──────────────────────────────────────────────────\nwatch(\n  () => props.sizes,\n  async (newSizes) => {\n    if (!newSizes || !firstPanelRef.value) return\n    // 모바일 responsive 방향 전환 중이면 sizes prop 무시\n    if (props.responsive && isMobile.value && props.direction === 'horizontal') return\n    if (Math.abs(newSizes[0] + newSizes[1] - 100) > 0.1) {\n      console.warn('[JSplitter] sizes 합계가 100이 아닙니다:', newSizes)\n      return\n    }\n    isUpdatingFromProp = true\n    try {\n      firstPanelRef.value.resize(newSizes[0])\n      await nextTick()\n    } finally {\n      isUpdatingFromProp = false\n    }\n    emit('resize', newSizes, 'prop')\n  },\n  { deep: true },\n)\n\n// ── 모바일 방향 전환 시 layout 이벤트 억제 ──────────────────────────────\nwatch(effectiveDirection, async () => {\n  isUpdatingFromProp = true\n  await nextTick()\n  await nextTick()\n  isUpdatingFromProp = false\n})\n\n// ── 명령형 API 헬퍼 ─────────────────────────────────────────────────\nfunction getSizes(): SplitterSizes {\n  return [\n    Math.round((firstPanelRef.value?.getSize() ?? effectiveDefaultSize.value) * 10) / 10,\n    Math.round((secondPanelRef.value?.getSize() ?? secondDefaultSize.value) * 10) / 10,\n  ]\n}\n\nasync function resizeFirst(size: number) {\n  if (!firstPanelRef.value) return\n  isUpdatingFromProp = true\n  try {\n    firstPanelRef.value.resize(size)\n    await nextTick()\n  } finally {\n    isUpdatingFromProp = false\n  }\n  const sizes: SplitterSizes = [size, 100 - size]\n  emit('update:sizes', sizes)\n  emit('resize', sizes, 'api')\n}\n\nasync function resizeSecond(size: number) {\n  if (!secondPanelRef.value) return\n  isUpdatingFromProp = true\n  try {\n    secondPanelRef.value.resize(size)\n    await nextTick()\n  } finally {\n    isUpdatingFromProp = false\n  }\n  const sizes: SplitterSizes = [100 - size, size]\n  emit('update:sizes', sizes)\n  emit('resize', sizes, 'api')\n}\n\nasync function resetToDefault() {\n  await resizeFirst(effectiveDefaultSize.value)\n}\n\nconst isFirstCollapsed = computed(() => _isFirstCollapsed.value)\nconst isSecondCollapsed = computed(() => _isSecondCollapsed.value)\n\nasync function collapseFirst() {\n  if (!firstPanelRef.value || !props.collapsibleFirst) return\n  const current = firstPanelRef.value.getSize()\n  if (current > props.collapsedSizeFirst) _firstCollapsedSize.value = current\n  if (props.animated) _isAnimating.value = true\n  // nextTick 동안 reka-ui가 minSize 변경을 감지해 layout을 재계산하면 _firstCollapsedSize가\n  // defaultSize로 덮어써지므로, nextTick이 끝날 때까지 handleLayout 추적을 차단\n  isUpdatingFromProp = true\n  _minSizeFirstOverride.value = 0\n  _maxSizeSecondOverride.value = 100\n  await nextTick()\n  isUpdatingFromProp = false\n  await resizeFirst(props.collapsedSizeFirst)\n  _isFirstCollapsed.value = true\n  if (props.animated) {\n    await new Promise<void>(resolve => setTimeout(resolve, props.animationDuration))\n    _isAnimating.value = false\n  }\n}\n\nasync function expandFirst() {\n  if (!firstPanelRef.value) return\n  const restoreSize = _firstCollapsedSize.value || effectiveDefaultSize.value\n  if (props.animated) _isAnimating.value = true\n  await resizeFirst(restoreSize)\n  // min/maxSize 복원 후 reka-ui가 레이아웃을 defaultSize로 재계산할 수 있으므로\n  // nextTick 후 다시 한번 size를 강제 적용\n  _minSizeFirstOverride.value = undefined\n  _maxSizeSecondOverride.value = undefined\n  await nextTick()\n  await resizeFirst(restoreSize)\n  _isFirstCollapsed.value = false\n  if (props.animated) {\n    await new Promise<void>(resolve => setTimeout(resolve, props.animationDuration))\n    _isAnimating.value = false\n  }\n}\n\nasync function collapseSecond() {\n  if (!secondPanelRef.value || !props.collapsibleSecond) return\n  const current = secondPanelRef.value.getSize()\n  if (current > props.collapsedSizeSecond) _secondCollapsedSize.value = current\n  if (props.animated) _isAnimating.value = true\n  isUpdatingFromProp = true\n  _minSizeSecondOverride.value = 0\n  _maxSizeFirstOverride.value = 100\n  await nextTick()\n  isUpdatingFromProp = false\n  await resizeSecond(props.collapsedSizeSecond)\n  _isSecondCollapsed.value = true\n  if (props.animated) {\n    await new Promise<void>(resolve => setTimeout(resolve, props.animationDuration))\n    _isAnimating.value = false\n  }\n}\n\nasync function expandSecond() {\n  if (!secondPanelRef.value) return\n  const restoreSize = _secondCollapsedSize.value || secondDefaultSize.value\n  if (props.animated) _isAnimating.value = true\n  await resizeSecond(restoreSize)\n  _minSizeSecondOverride.value = undefined\n  _maxSizeFirstOverride.value = undefined\n  await nextTick()\n  await resizeSecond(restoreSize)\n  _isSecondCollapsed.value = false\n  if (props.animated) {\n    await new Promise<void>(resolve => setTimeout(resolve, props.animationDuration))\n    _isAnimating.value = false\n  }\n}\n\ndefineExpose<JSplitterMethods>({\n  resizeFirst,\n  resizeSecond,\n  getSizes,\n  collapseFirst,\n  expandFirst,\n  collapseSecond,\n  expandSecond,\n  resetToDefault,\n  isFirstCollapsed,\n  isSecondCollapsed,\n})\n</script>\n\n<template>\n  <ResizablePanelGroup\n    :direction=\"effectiveDirection\"\n    :class=\"cn('jsplitter-group min-h-0 min-w-0', $props.class)\"\n    @layout=\"handleLayout\"\n  >\n    <!-- 첫 번째 패널 (좌측/상단) -->\n    <ResizablePanel\n      ref=\"firstPanelRef\"\n      :default-size=\"effectiveDefaultSize\"\n      :min-size=\"_effectiveMinSizeFirst\"\n      :max-size=\"_effectiveMaxSizeFirst\"\n      :class=\"gap > 0 ? (effectiveDirection === 'horizontal' ? 'pr-[calc(var(--gap)/2)]' : 'pb-[calc(var(--gap)/2)]') : ''\"\n      :style=\"[gap > 0 ? { '--gap': `${gap}px` } : {}, _isAnimating ? { transition: `flex ${animationDuration}ms ease` } : {}]\"\n    >\n      <slot name=\"first\" />\n      <!-- direction=\"horizontal\"일 때 left, vertical일 때 top으로도 사용 가능 -->\n      <slot name=\"left\" />\n      <slot name=\"top\" />\n    </ResizablePanel>\n\n    <!-- 크기 조정 핸들 -->\n    <ResizableHandle :with-handle=\"withHandle\" class=\"jsplitter-handle\" />\n\n    <!-- 두 번째 패널 (우측/하단) -->\n    <ResizablePanel\n      ref=\"secondPanelRef\"\n      :default-size=\"secondDefaultSize\"\n      :min-size=\"_effectiveMinSizeSecond\"\n      :max-size=\"_effectiveMaxSizeSecond\"\n      :class=\"gap > 0 ? (effectiveDirection === 'horizontal' ? 'pl-[calc(var(--gap)/2)]' : 'pt-[calc(var(--gap)/2)]') : ''\"\n      :style=\"[gap > 0 ? { '--gap': `${gap}px` } : {}, _isAnimating ? { transition: `flex ${animationDuration}ms ease` } : {}]\"\n    >\n      <slot name=\"second\" />\n      <!-- direction=\"horizontal\"일 때 right, vertical일 때 bottom으로도 사용 가능 -->\n      <slot name=\"right\" />\n      <slot name=\"bottom\" />\n    </ResizablePanel>\n  </ResizablePanelGroup>\n</template>\n\n<style scoped>\n/* ── overflow 보호 ──────────────────────────────────────────────────── */\n:deep(.jsplitter-group [data-panel]) {\n  min-width: 0;\n  min-height: 0;\n}\n\n/* ── horizontal 핸들: 8px 히트영역 ─────────────────────────────────── */\n:deep(.jsplitter-handle[data-orientation=\"horizontal\"]) {\n  width: 8px !important;\n  background: transparent !important;\n  position: relative;\n  z-index: 3;\n  transition: background 0.15s ease;\n}\n\n/* ── vertical 핸들: 8px 히트영역 ───────────────────────────────────── */\n:deep(.jsplitter-handle[data-orientation=\"vertical\"]) {\n  height: 8px !important;\n  background: transparent !important;\n  position: relative;\n  z-index: 3;\n  transition: background 0.15s ease;\n}\n\n/* ── 시각선: 1px (after:w-1 override) ──────────────────────────────── */\n:deep(.jsplitter-handle::after) {\n  width: 1px !important;\n  background: hsl(var(--border)) !important;\n  transition: background 0.15s ease, width 0.12s ease !important;\n}\n\n:deep(.jsplitter-handle[data-orientation=\"vertical\"]::after) {\n  height: 1px !important;\n  width: 100% !important;\n}\n\n/* ── 그립 도트 인디케이터 (::before) ───────────────────────────────── */\n:deep(.jsplitter-handle::before) {\n  content: '';\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: 3px;\n  height: 20px;\n  background-image: radial-gradient(circle, hsl(var(--muted-foreground) / 0.5) 1px, transparent 1px);\n  background-size: 3px 6px;\n  background-repeat: repeat-y;\n  border-radius: 2px;\n  opacity: 0.5;\n  transition: opacity 0.15s ease;\n  pointer-events: none;\n  z-index: 4;\n}\n\n:deep(.jsplitter-handle[data-orientation=\"vertical\"]::before) {\n  width: 20px;\n  height: 3px;\n  background-size: 6px 3px;\n  background-repeat: repeat-x;\n  background-image: radial-gradient(circle, hsl(var(--muted-foreground) / 0.5) 1px, transparent 1px);\n}\n\n/* ── hover ──────────────────────────────────────────────────────────── */\n:deep(.jsplitter-handle:hover) {\n  background: hsl(var(--primary) / 0.04) !important;\n}\n\n:deep(.jsplitter-handle:hover::after) {\n  width: 2px !important;\n  background: hsl(var(--primary) / 0.55) !important;\n}\n\n:deep(.jsplitter-handle:hover::before) {\n  opacity: 1;\n}\n\n/* ── drag / active ──────────────────────────────────────────────────── */\n:deep(.jsplitter-handle[data-state=\"drag\"]),\n:deep(.jsplitter-handle:active) {\n  background: hsl(var(--primary) / 0.06) !important;\n}\n\n:deep(.jsplitter-handle[data-state=\"drag\"]::after),\n:deep(.jsplitter-handle:active::after) {\n  width: 2px !important;\n  background: hsl(var(--primary)) !important;\n}\n\n:deep(.jsplitter-handle[data-state=\"drag\"]::before),\n:deep(.jsplitter-handle:active::before) {\n  opacity: 1;\n  background-image: radial-gradient(circle, hsl(var(--primary) / 0.65) 1px, transparent 1px);\n}\n</style>\n"],"names":["COLLAPSE_OPEN_THRESHOLD","props","__props","emit","__emit","isMobile","useBreakpoint","effectiveDirection","computed","effectiveDefaultSize","secondDefaultSize","firstPanelRef","ref","secondPanelRef","_firstCollapsedSize","_secondCollapsedSize","_isFirstCollapsed","_isSecondCollapsed","_isAnimating","_minSizeFirstOverride","_minSizeSecondOverride","_maxSizeFirstOverride","_maxSizeSecondOverride","_effectiveMinSizeFirst","_effectiveMinSizeSecond","_effectiveMaxSizeFirst","_effectiveMaxSizeSecond","isUpdatingFromProp","handleLayout","layout","sizes","watch","newSizes","nextTick","getSizes","resizeFirst","size","resizeSecond","resetToDefault","isFirstCollapsed","isSecondCollapsed","collapseFirst","current","resolve","expandFirst","restoreSize","collapseSecond","expandSecond","__expose","_createBlock","_unref","ResizablePanelGroup","_normalizeClass","cn","$props","_createVNode","ResizablePanel","_renderSlot","_ctx","ResizableHandle"],"mappings":"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"}