블록 UX: 삭제/복제 버튼 및 단축키 추가
CI / test (push) Failing after 6m0s
CI / pr_and_merge (push) Has been skipped

This commit is contained in:
2025-11-18 16:28:46 +09:00
parent cf04c6e56c
commit 8494bd64bc
4 changed files with 207 additions and 1 deletions
+41 -1
View File
@@ -44,6 +44,8 @@ export default function EditorPage() {
const moveBlock = useEditorStore((state) => state.moveBlock);
const undo = useEditorStore((state) => state.undo);
const redo = useEditorStore((state) => state.redo);
const removeBlock = useEditorStore((state) => state.removeBlock);
const duplicateBlock = useEditorStore((state) => state.duplicateBlock);
const [editingBlockId, setEditingBlockId] = useState<string | null>(null);
const [editingText, setEditingText] = useState("");
@@ -200,7 +202,8 @@ export default function EditorPage() {
const rootBlocks = blocks.filter((block) => !block.sectionId);
// 에디터 전역에서 Undo/Redo 단축키(Cmd/Ctrl+Z, Cmd/Ctrl+Shift+Z)
// 에디터 전역에서 Undo/Redo 단축키(Cmd/Ctrl+Z, Cmd/Ctrl+Shift+Z),
// Delete/Backspace 기반 삭제, Cmd/Ctrl+D 기반 복제,
// ArrowUp/ArrowDown을 이용한 선택 블록 이동을 처리한다.
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
@@ -237,8 +240,29 @@ export default function EditorPage() {
const isMac = navigator.platform.toLowerCase().includes("mac");
const metaKey = isMac ? event.metaKey : event.ctrlKey;
// Delete / Backspace 로 선택된 블록 삭제
if (event.key === "Delete" || event.key === "Backspace") {
const { selectedBlockId: currentSelectedId } = (useEditorStore as any).getState();
if (currentSelectedId) {
event.preventDefault();
removeBlock(currentSelectedId);
}
return;
}
// Cmd/Ctrl 없는 경우에는 여기서 종료한다.
if (!metaKey) return;
// Cmd/Ctrl + D → 현재 선택된 블록 복제
if (event.key.toLowerCase() === "d") {
const { selectedBlockId: currentSelectedId } = (useEditorStore as any).getState();
if (currentSelectedId) {
event.preventDefault();
duplicateBlock(currentSelectedId);
}
return;
}
// Cmd/Ctrl + Shift + Z → Redo
if (event.key.toLowerCase() === "z" && event.shiftKey) {
event.preventDefault();
@@ -381,6 +405,22 @@ export default function EditorPage() {
<h2 className="font-medium mb-2"> </h2>
{selectedBlockId ? (
<div className="space-y-3">
<div className="flex gap-2 text-[11px]">
<button
type="button"
className="flex-1 rounded border border-slate-700 bg-slate-900 px-2 py-1 text-slate-100 hover:bg-red-900/60 hover:border-red-700"
onClick={() => removeBlock(selectedBlockId)}
>
</button>
<button
type="button"
className="flex-1 rounded border border-slate-700 bg-slate-900 px-2 py-1 text-slate-100 hover:bg-slate-800"
onClick={() => duplicateBlock(selectedBlockId)}
>
</button>
</div>
{(() => {
const selectedBlock = blocks.find((b) => b.id === selectedBlockId);
if (!selectedBlock) return null;