toolbar / layer panel / inspector 연결
Figma-like editor는 캔버스만으로 완성되지 않습니다. 사용자는 도구를 고르고, 레이어를 선택하고, 속성을 바꿔야 합니다.
이번 레슨에서는 toolbar, layer panel, inspector가 editor core와 어떻게 연결되는지 정리합니다.
panel은 core snapshot을 읽고 action을 보낸다
toolbar, layer panel, inspector는 상태를 직접 복제하지 않습니다. core snapshot을 읽어서 그리고, 변경은 action으로 돌려보냅니다.
function renderToolbar(root, editor) {
root.querySelectorAll("[data-tool]").forEach((button) => {
button.addEventListener("click", () => {
editor.dispatch({ type: "setTool", tool: button.dataset.tool });
});
});
}
function renderLayerPanel(root, snapshot, editor) {
root.replaceChildren(...snapshot.drawList.map((node) => {
const row = document.createElement("button");
row.textContent = node.name;
row.className = snapshot.selection.ids.includes(node.id) ? "selected" : "";
row.onclick = () => editor.dispatch({ type: "setSelection", ids: [node.id] });
return row;
}));
}
function commitInspectorChange(editor, nodeId, patch) {
editor.dispatch({
type: "updateNode",
id: nodeId,
patch,
commit: true
});
}
이 구조를 쓰면 UI 패널은 언제든 다시 그릴 수 있는 projection이고, 문서 변경 기록은 core command로 모입니다.
panel action을 좁게 정의한다
UI가 임의로 document를 수정하지 못하게 action을 좁게 둡니다.
type EditorAction =
| { type: "setTool"; tool: "select" | "hand" | "rect" | "text" | "image" }
| { type: "setSelection"; ids: NodeId[] }
| { type: "updateNode"; id: NodeId; patch: Partial<SceneNode>; commit: boolean }
| { type: "reorderChild"; parentId: NodeId; childId: NodeId; toIndex: number }
| { type: "undo" }
| { type: "redo" };
function bindInspectorNumber(input, editor, nodeId, property) {
input.addEventListener("change", () => {
editor.dispatch({
type: "updateNode",
id: nodeId,
patch: { [property]: Number(input.value) },
commit: true
});
});
}
패널은 action을 보낼 뿐이고, command 생성과 history 기록은 core가 결정합니다.
toolbar는 tool mode를 바꾼다
toolbar 버튼은 현재 tool을 바꿉니다.
select
hand
rectangle
text
image
tool mode는 transient editor state입니다. 문서 JSON에 저장할 값은 아니지만, 현재 입력 해석에 영향을 줍니다.
layer panel은 scene graph의 projection이다
layer panel은 node tree를 UI로 보여주는 projection입니다.
scene node tree
-> layer rows
row를 클릭하면 selection이 바뀌고, row를 drag하면 layer order가 바뀝니다. 하지만 source of truth는 panel row가 아니라 scene graph입니다.
inspector는 selected node를 편집한다
inspector는 선택된 node의 속성을 보여주고 수정합니다.
selection
-> selected nodes
-> common properties
-> property controls
속성 변경은 command로 기록해야 undo/redo가 됩니다.
오늘의 핵심
toolbar, layer panel, inspector는 모두 editor core의 projection이거나 action source입니다.
toolbar -> tool state
layer panel -> scene graph + selection
inspector -> selected node properties + commands
UI가 상태를 복제하지 않고 core와 동기화되는 구조가 중요합니다.