Merge branch 'feature/builder-5-ux'
This commit is contained in:
+62
-2
@@ -1,8 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import type { CSSProperties, ReactNode } from "react";
|
||||
import { useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
DndContext,
|
||||
PointerSensor,
|
||||
@@ -42,6 +41,8 @@ export default function EditorPage() {
|
||||
const replaceBlocks = useEditorStore((state) => state.replaceBlocks);
|
||||
const reorderBlocks = useEditorStore((state) => state.reorderBlocks);
|
||||
const moveBlock = useEditorStore((state) => state.moveBlock);
|
||||
const undo = useEditorStore((state) => state.undo);
|
||||
const redo = useEditorStore((state) => state.redo);
|
||||
|
||||
const [editingBlockId, setEditingBlockId] = useState<string | null>(null);
|
||||
const [editingText, setEditingText] = useState("");
|
||||
@@ -198,6 +199,65 @@ export default function EditorPage() {
|
||||
|
||||
const rootBlocks = blocks.filter((block) => !block.sectionId);
|
||||
|
||||
// 에디터 전역에서 Undo/Redo 단축키(Cmd/Ctrl+Z, Cmd/Ctrl+Shift+Z)와
|
||||
// ArrowUp/ArrowDown을 이용한 선택 블록 이동을 처리한다.
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
// 방향키로 선택된 블록을 위/아래로 이동 (순서 변경이 아니라 선택만 이동)
|
||||
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
||||
const { blocks: currentBlocks, selectedBlockId: currentSelectedId, selectBlock: storeSelectBlock } =
|
||||
(useEditorStore as any).getState();
|
||||
|
||||
if (!currentBlocks.length) return;
|
||||
|
||||
const currentIndex = currentSelectedId
|
||||
? currentBlocks.findIndex((b: Block) => b.id === currentSelectedId)
|
||||
: -1;
|
||||
|
||||
let nextIndex = currentIndex;
|
||||
|
||||
if (event.key === "ArrowDown") {
|
||||
nextIndex = currentIndex < currentBlocks.length - 1 ? currentIndex + 1 : currentIndex;
|
||||
} else if (event.key === "ArrowUp") {
|
||||
nextIndex = currentIndex > 0 ? currentIndex - 1 : currentIndex;
|
||||
}
|
||||
|
||||
if (nextIndex !== -1 && nextIndex !== currentIndex) {
|
||||
event.preventDefault();
|
||||
const nextId = currentBlocks[nextIndex]?.id;
|
||||
if (nextId) {
|
||||
storeSelectBlock(nextId);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const isMac = navigator.platform.toLowerCase().includes("mac");
|
||||
const metaKey = isMac ? event.metaKey : event.ctrlKey;
|
||||
|
||||
if (!metaKey) return;
|
||||
|
||||
// Cmd/Ctrl + Shift + Z → Redo
|
||||
if (event.key.toLowerCase() === "z" && event.shiftKey) {
|
||||
event.preventDefault();
|
||||
redo();
|
||||
return;
|
||||
}
|
||||
|
||||
// Cmd/Ctrl + Z → Undo
|
||||
if (event.key.toLowerCase() === "z") {
|
||||
event.preventDefault();
|
||||
undo();
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => {
|
||||
window.removeEventListener("keydown", handleKeyDown);
|
||||
};
|
||||
}, [undo, redo]);
|
||||
|
||||
const renderBlocks = (targetBlocks: Block[]) =>
|
||||
targetBlocks.map((block) => {
|
||||
const isSelected = block.id === selectedBlockId;
|
||||
|
||||
Reference in New Issue
Block a user