Skip to content

Feature/sidebar#20

Open
Nago730 wants to merge 19 commits intodevelopfrom
feature/sidebar
Open

Feature/sidebar#20
Nago730 wants to merge 19 commits intodevelopfrom
feature/sidebar

Conversation

@Nago730
Copy link
Copy Markdown
Contributor

@Nago730 Nago730 commented Feb 24, 2026

구현 핵심 내용

1. Portal 방식의 오버레이 도입 (SelectionOverlay.tsx)

  • 기존 방식에선 overflow-hidden(이미지 마스킹 시 필수) 등 상황에서 오버레이가 클리핑됨

2. nodes 인접 리스트 인덱싱 도입 (트리 탐색 성능 O(n) ->O(1)로 개선)

도입한 자료구조

  • nodeMap: id를 키로 사용하는 일반 객체 (immer 내부에서 Map 사용 어려움)
  • childrenMap: parent_id를 키로 가지며 이미 정렬된 자녀 노드들의 배열을 값으로 가짐. 부모 ID만 알면 즉시 정렬된 자녀 리스트를 얻을 수 있음

기존:

  • 노드 조회 (find) → O(n)
  • 자녀 노드 렌더링 (filter & sort) → O(n) * O(k log k)
  • 노드 삭제 (filter 후 자식을 다시 filter) → O(n^2)

개선 후:

  • 노드 조회 (find) → O(1)
  • 자녀 노드 렌더링 → O(1)
  • 노드 삭제 시 childrenMap으로 후손 ID를 즉시 수집 가능 → O(n)
  • 5곳 이상의 코드에서 nodes를 선형적 순회(find 등)하는 코드 발견 후 개선

결론: 트레이드오프

  • 이 방식에는 추가적인 메모리 사용이라는 비용이 발생. 하지만 에디터 환경에서 수천 개의 객체 참조를 Map에 저장하는 비용은 수 밀리초마다 발생하는 O(n) 연산의 CPU 비용보다 현저히 낮음.

3-1. Fixed, Relative, Fill, Fit Content 기능 도입

  • 기존 Rnd 기반 EditorNodeWrapper에서는 내부 라이브러리 동작 방식 width, height의 인라인 방식때매 자동 레이아웃 구현이 어려움
  • 이러한 이유로 제 2의 래퍼(FlowNodeWrapper) 구현하기로 결정(일단 임시 느낌). 현재 진행 상황에서 dnd는 적용이 안 되고 오직 CSS 기반 렌더링만 기능하는 래퍼임.

3-2. FlowNodeWrapper 도입 (기존의 EditorNodeWrapper와 대비)

  • Canvas.tsx에서 분기처리 후 둘 중 하나 선택
  • 현재 부모가 Stack, 현재노드가 Relative일 때만 FlowNodeWrapper 적용. 분기처리는 고도화 필요
  • const isFlowItem = parent?.type === "Stack" && node.style.position === "relative";

향후 구현 방향

  • FlowNodeWrapper를 기반으로 자식끼리만 바꾸는 기능을 구현해도 괜찮을 듯.

1. Reorder 방식의 장점 (vs react-rnd)

  • 자연스러운 레이아웃 시프트: Rnd는 다른 아이템의 위치를 전혀 신경 쓰지 않지만, Reorder는 아이템이 드래그될 때 주변 아이템들이 자동으로 비켜주는 애니메이션을 내장하고 있습니다.
  • 상태 동기화의 단순함: onReorder 콜백 하나로 배열의 순서만 바꿔주면 되므로, 일일이 x, y 좌표를 계산하고 저장할 필요가 없습니다.
    성능: framer-motion은 레이아웃 프로젝션 기술을 사용해 매우 부드러운 60fps 애니메이션을 제공합니다.

2. 고려해야 할 단점 (제약 사항)

  • 컨테이너 간 이동 (Cross-Stack Dragging): Reorder는 기본적으로 같은 부모 안에서의 순서 변경에 최적화되어 있습니다. "Stack A에 있는 버튼을 Stack B로 옮기는 작업"은 Reorder만으로는 구현하기 까다롭고, 별도의 드롭 존(Drop Zone) 로직이나 하이브리드 방식(dnd-kit 병행 등)이 필요할 수 있습니다.
  • 리사이징 기능 부재: Rnd는 드래그와 리사이즈 핸들을 모두 제공하지만, Reorder는 수동 리사이즈 핸들을 직접 만들어 붙여야 합니다. (물론 우리는 어차피 커스텀 핸들을 만들 계획이므로 큰 문제는 아닐 수 있습니다.)

파일 변경 사항

  • 파일: apps/editor/src/app/editor/page.tsx
  • 문제 & 해결: overflow-hidden 추가 이유: 사이드바 내부 요소가 커지면 사이드바에 드래그바가 생기며 에디터 페이지에도 드래그바가 생김. 사이드바 드래그바를 none으로 설정했으나 에디터 화면에 드래그바가 생기는 원인은 해결 못 함. 원천을 차단하기 위해 overflow-hidden을 설정함.

  • 파일: apps/editor/src/components/editor/Canvas.tsx
  • 변경사항: FlowNodeWrapper 혹은 EditorNodeWrapper 중 뭘 사용할지 분기처리하는 코드 포함. 그러나 향후에 분리해야 할 듯(이 PR 머지되기 전에 분리할 수도)

  • 파일: apps/editor/src/widgets/left-sidebar/model/nodeInsertRules.ts
  • 설명: 레이어 패널(노드 트리구조로 보여주는 패널)에서 스택에 우클릭 시 어떤 것들이 삽입한지 정의

  • 파일: apps/editor/src/widgets/left-sidebar/ui/LayerContextMenu.tsx
  • 설명: 레이어 패널 우클릭 컨텍스트 메뉴

  • 파일: apps/editor/src/widgets/left-sidebar/ui/SubPanel.tsx
  • 설명: 요소가 넘쳐도 스크롤바 안 생기게 인라인 style로 scrollbarWidth: 'none' 추가

  • 파일: packages/ui/src/components/Stack.tsx
  • 설명: 패키지/ui 파일인데, data-attribute에 data-stack-direction 추가함. 노드의 너비 fill, fit 등 바꿀 때, 입힐 css 속성을 정하는 것에 부모의 flex-direction이 영향을 줌.

  • 파일: packages/ui/src/core/SelectionOverlay.tsx
  • 설명: Portal 방식 오버레이 컴포넌트 로직 및 UI 총집합 파일

사이징/레이아웃 관련 비즈니스 로직 파일

  • apps/editor/src/widgets/right-sidebar/hooks/useSizeModeChange.ts
  • apps/editor/src/widgets/right-sidebar/lib/sizingConversion.ts
  • apps/editor/src/widgets/right-sidebar/lib/sizingOptions.ts
  • packages/ui/src/utils/resolveSizeStyle.ts

- processNodeStyles에서 padding shorthand/longhand 동시 사용 방지
- 에디터 페이지 최상위 컨테이너에 overflow-hidden 적용
- 좌우 사이드바 스크롤바 숨김 (scrollbarWidth: none)
@Nago730 Nago730 requested a review from y-minion February 24, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant