59 lines
1.6 KiB
TypeScript
59 lines
1.6 KiB
TypeScript
|
|
'use client';
|
||
|
|
|
||
|
|
import React, { useRef, ReactNode } from 'react';
|
||
|
|
import { UseDragReturn } from '../types';
|
||
|
|
|
||
|
|
interface DocumentContentProps {
|
||
|
|
children: ReactNode;
|
||
|
|
zoom: number;
|
||
|
|
drag: UseDragReturn;
|
||
|
|
enableDrag?: boolean;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 문서 콘텐츠 영역
|
||
|
|
* - 줌 적용
|
||
|
|
* - 드래그 이동 (줌 100% 초과 시)
|
||
|
|
*/
|
||
|
|
export function DocumentContent({
|
||
|
|
children,
|
||
|
|
zoom,
|
||
|
|
drag,
|
||
|
|
enableDrag = true,
|
||
|
|
}: DocumentContentProps) {
|
||
|
|
const containerRef = useRef<HTMLDivElement>(null);
|
||
|
|
const contentRef = useRef<HTMLDivElement>(null);
|
||
|
|
|
||
|
|
// 드래그는 줌 100% 초과 시에만 활성화
|
||
|
|
const isDragEnabled = enableDrag && zoom > 100;
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
ref={containerRef}
|
||
|
|
className="flex-1 overflow-auto bg-gray-100 relative print:overflow-visible print:bg-white"
|
||
|
|
{...(isDragEnabled ? drag.handlers : {})}
|
||
|
|
style={{
|
||
|
|
cursor: isDragEnabled ? (drag.isDragging ? 'grabbing' : 'grab') : 'default',
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<div
|
||
|
|
ref={contentRef}
|
||
|
|
className="p-4 origin-top-left transition-transform duration-150 ease-out print:p-0 print:transform-none"
|
||
|
|
style={{
|
||
|
|
transform: `scale(${zoom / 100}) translate(${drag.position.x / (zoom / 100)}px, ${drag.position.y / (zoom / 100)}px)`,
|
||
|
|
minWidth: '800px',
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
{children}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 모바일 줌 힌트 */}
|
||
|
|
{zoom === 100 && enableDrag && (
|
||
|
|
<div className="sm:hidden absolute bottom-4 left-1/2 -translate-x-1/2 bg-black/70 text-white text-xs px-3 py-1.5 rounded-full print:hidden">
|
||
|
|
확대 후 드래그로 이동
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|