레이어 관리 구현

This commit is contained in:
dohyeons
2025-10-01 16:17:41 +09:00
parent 722a413916
commit 172ecf34b3
2 changed files with 134 additions and 1 deletions

View File

@@ -345,6 +345,12 @@ interface ReportDesignerContextType {
makeSameWidth: () => void;
makeSameHeight: () => void;
makeSameSize: () => void;
// 레이어 관리
bringToFront: () => void;
sendToBack: () => void;
bringForward: () => void;
sendBackward: () => void;
}
const ReportDesignerContext = createContext<ReportDesignerContextType | undefined>(undefined);
@@ -769,6 +775,87 @@ export function ReportDesignerProvider({ reportId, children }: { reportId: strin
toast({ title: "크기 조정 완료", description: "같은 크기로 조정되었습니다." });
}, [getSelectedComponents, toast]);
// 레이어 관리 함수들
const bringToFront = useCallback(() => {
if (!selectedComponentId && selectedComponentIds.length === 0) return;
const idsToUpdate =
selectedComponentIds.length > 0 ? selectedComponentIds : ([selectedComponentId].filter(Boolean) as string[]);
const maxZIndex = Math.max(...components.map((c) => c.zIndex));
setComponents((prev) =>
prev.map((c) => {
if (idsToUpdate.includes(c.id)) {
return { ...c, zIndex: maxZIndex + 1 };
}
return c;
}),
);
toast({ title: "레이어 변경", description: "맨 앞으로 이동했습니다." });
}, [selectedComponentId, selectedComponentIds, components, toast]);
const sendToBack = useCallback(() => {
if (!selectedComponentId && selectedComponentIds.length === 0) return;
const idsToUpdate =
selectedComponentIds.length > 0 ? selectedComponentIds : ([selectedComponentId].filter(Boolean) as string[]);
const minZIndex = Math.min(...components.map((c) => c.zIndex));
setComponents((prev) =>
prev.map((c) => {
if (idsToUpdate.includes(c.id)) {
return { ...c, zIndex: minZIndex - 1 };
}
return c;
}),
);
toast({ title: "레이어 변경", description: "맨 뒤로 이동했습니다." });
}, [selectedComponentId, selectedComponentIds, components, toast]);
const bringForward = useCallback(() => {
if (!selectedComponentId && selectedComponentIds.length === 0) return;
const idsToUpdate =
selectedComponentIds.length > 0 ? selectedComponentIds : ([selectedComponentId].filter(Boolean) as string[]);
setComponents((prev) => {
const sorted = [...prev].sort((a, b) => a.zIndex - b.zIndex);
const updated = sorted.map((c, index) => ({ ...c, zIndex: index }));
return updated.map((c) => {
if (idsToUpdate.includes(c.id)) {
return { ...c, zIndex: Math.min(c.zIndex + 1, updated.length - 1) };
}
return c;
});
});
toast({ title: "레이어 변경", description: "한 단계 앞으로 이동했습니다." });
}, [selectedComponentId, selectedComponentIds, toast]);
const sendBackward = useCallback(() => {
if (!selectedComponentId && selectedComponentIds.length === 0) return;
const idsToUpdate =
selectedComponentIds.length > 0 ? selectedComponentIds : ([selectedComponentId].filter(Boolean) as string[]);
setComponents((prev) => {
const sorted = [...prev].sort((a, b) => a.zIndex - b.zIndex);
const updated = sorted.map((c, index) => ({ ...c, zIndex: index }));
return updated.map((c) => {
if (idsToUpdate.includes(c.id)) {
return { ...c, zIndex: Math.max(c.zIndex - 1, 0) };
}
return c;
});
});
toast({ title: "레이어 변경", description: "한 단계 뒤로 이동했습니다." });
}, [selectedComponentId, selectedComponentIds, toast]);
// 캔버스 설정 (기본값)
const [canvasWidth, setCanvasWidth] = useState(210);
const [canvasHeight, setCanvasHeight] = useState(297);
@@ -1180,6 +1267,11 @@ export function ReportDesignerProvider({ reportId, children }: { reportId: strin
makeSameWidth,
makeSameHeight,
makeSameSize,
// 레이어 관리
bringToFront,
sendToBack,
bringForward,
sendBackward,
};
return <ReportDesignerContext.Provider value={value}>{children}</ReportDesignerContext.Provider>;