@jbpark/live-editor 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 jbpark
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.ko.md CHANGED
@@ -12,20 +12,25 @@
12
12
  live-editor/
13
13
  ├─ src/
14
14
  │ ├─ components/
15
- │ │ ├─ Context/ # 전역 상태 관리
16
- │ │ ├─ Dnd/ # 드래그 앤 드롭 시스템 및 편집 패널
17
- │ │ ├─ Editor/ # 코드 에디터
18
- │ │ ├─ Error/ # 에러 바운더리
19
- │ │ ├─ Frame/ # iframe/shadow DOM 프리뷰 격리
20
- │ │ └─ Preview/ # 격리된 프리뷰 런타임
15
+ │ │ ├─ context/ # 전역 상태 관리
16
+ │ │ ├─ dnd/ # 드래그 앤 드롭 시스템 및 편집 패널
17
+ │ │ │ └─ panel/ # 속성 패널 필드 에디터
18
+ │ │ ├─ editor/ # CodeMirror 코드 에디터
19
+ │ │ ├─ error/ # 에러 바운더리
20
+ │ │ ├─ frame/ # iframe/shadow DOM 프리뷰 격리
21
+ │ │ └─ preview/ # 격리된 프리뷰 런타임
21
22
  │ ├─ pages/
22
- │ │ └─ Editor/ # 로컬 개발용 에디터 (에디터 + DnD 전환)
23
- │ ├─ utils/ast/ # AST 조작 및 코드 생성
24
- │ ├─ constants/ # 상수설정
25
- │ ├─ types/ # TypeScript 타입 정의
26
- └─ main.tsx # 로컬 개발 앱 엔트리
27
- ├─ demos/ # 문서용 독립 iframe 데모
28
- ├─ website/ # Docusaurus 문서 사이트
23
+ │ │ └─ editor/ # 로컬 개발용 에디터 (에디터 + DnD 전환)
24
+ │ ├─ utils/
25
+ ├─ ast/ # AST 조작 코드 생성
26
+ ├─ tailwind/ # Tailwind 테마 헬퍼
27
+ │ ├─ cache.ts # 바운디드 LRU 캐시
28
+ │ │ └─ selection.ts # 다중 선택 헬퍼
29
+ ├─ constants/ # 상수 설정
30
+ │ ├─ types/ # TypeScript 타입 정의
31
+ │ └─ main.tsx # 로컬 개발 앱 엔트리
32
+ ├─ demos/ # 문서용 독립 iframe 데모
33
+ ├─ website/ # Docusaurus 문서 사이트
29
34
  └─ package.json
30
35
  ```
31
36
 
@@ -38,6 +43,76 @@ live-editor/
38
43
  - **프리뷰 런타임**: 컴파일된 결과를 DOM/CSS 격리를 위해 iframe 안에서 렌더링합니다 (보안 샌드박스는 아닙니다 — [보안 참고사항](#-보안-참고사항) 참고).
39
44
  - **강력한 드래그 앤 드롭**: `@dnd-kit` 기반으로 부드러운 정렬과 배치를 지원합니다.
40
45
 
46
+ ## 📦 설치
47
+
48
+ ```bash
49
+ pnpm add @jbpark/live-editor react react-dom
50
+ ```
51
+
52
+ `react`와 `react-dom`(>= 19)은 peer dependency입니다. `prettier`(>= 3)는 선택적
53
+ peer로, 에디터의 저장 시 포맷(format-on-save)을 쓰려면 함께 설치하세요. 없어도
54
+ 에디터는 정상 동작하며 포맷만 건너뜁니다.
55
+
56
+ ## 🧑‍💻 사용법
57
+
58
+ 스타일시트를 앱 루트 근처에서 한 번 import하세요 — **필수**이며 JS 엔트리가
59
+ 자동으로 불러오지 않습니다:
60
+
61
+ ```tsx
62
+ import { useState } from 'react';
63
+
64
+ import Live from '@jbpark/live-editor';
65
+ import '@jbpark/live-editor/style.css';
66
+
67
+ // 필수 — JS 엔트리가 import하지 않음
68
+
69
+ const SAMPLE = `
70
+ import * as ui from 'ui-kit';
71
+
72
+ const App = () => (
73
+ <div className="p-6 space-y-2">
74
+ <ui.Typography.Title level={3}>Hello</ui.Typography.Title>
75
+ <ui.Button type="primary">Edit me</ui.Button>
76
+ </div>
77
+ );
78
+
79
+ export default App;
80
+ `;
81
+
82
+ export default function Example() {
83
+ const [code, setCode] = useState(SAMPLE);
84
+
85
+ return (
86
+ <Live>
87
+ <Live.Editor value={code} onChange={setCode} />
88
+ <Live.Preview showError frame={{ mode: 'iframe', syncStyle: true }} />
89
+ </Live>
90
+ );
91
+ }
92
+ ```
93
+
94
+ 전체 가이드(Tailwind가 프리뷰에 반영되는 방식, 커스텀 패널 등)는
95
+ [문서 사이트](https://live-editor-lab.vercel.app)를 참고하세요.
96
+
97
+ ## 🧩 엔트리 포인트
98
+
99
+ 패키지는 서브패스 export를 제공해, 한 기능 영역만 필요한 소비자가 나머지를
100
+ 번들에 포함하지 않도록 합니다(예: 프리뷰 전용 빌드에는 CodeMirror 미포함) —
101
+ [#194](https://github.com/pjb0811/live-editor/issues/194) 참고:
102
+
103
+ | Import | 내용 |
104
+ | ------------------------------------ | -------------------------------------- |
105
+ | `@jbpark/live-editor` | 전체 (`Live` 프로바이더 + 모든 서피스) |
106
+ | `@jbpark/live-editor/provider` | 공유 편집 컨텍스트 프로바이더만 |
107
+ | `@jbpark/live-editor/dnd` | 드래그 앤 드롭 캔버스 + 속성 패널 |
108
+ | `@jbpark/live-editor/editor` | CodeMirror 코드 에디터 |
109
+ | `@jbpark/live-editor/preview` | 격리된 프리뷰 런타임 |
110
+ | `@jbpark/live-editor/error` | 에러 바운더리 |
111
+ | `@jbpark/live-editor/utils` | 컴파일/섹션 헬퍼 |
112
+ | `@jbpark/live-editor/utils/ast` | AST 조작 및 코드 생성 |
113
+ | `@jbpark/live-editor/utils/tailwind` | Tailwind 테마 헬퍼 |
114
+ | `@jbpark/live-editor/style.css` | 컴파일된 스타일시트 (필수) |
115
+
41
116
  ## 🔒 보안 참고사항
42
117
 
43
118
  - 프리뷰 `<iframe>`(`src/components/frame/iframe.tsx`)의 `sandbox` prop은 **실제 보안 경계가 아닙니다**. 컴파일된 프리뷰 코드는 host 페이지 자신의 JS realm에서 `new Function(...)`으로 실행되며(`src/utils/index.ts`의 `compileModule`), iframe에는 그 결과로 생성된 React 엘리먼트만 `contentDocument`에 포탈되어 DOM/CSS 렌더링 용도로만 쓰입니다. iframe 자체는 사용자 코드를 실행하지 않습니다.
@@ -58,7 +133,10 @@ live-editor/
58
133
  - Node.js: 20.x 이상
59
134
  - **pnpm**: 10.x 이상 ([Corepack](https://nodejs.org/api/corepack.html)으로 관리)
60
135
 
61
- ## 🚀 시작하기
136
+ ## 🚀 개발 (이 저장소)
137
+
138
+ > Live Editor 자체를 개발할 때 참고하세요. 패키지를 앱에서 _사용_ 하려면
139
+ > 위의 [설치](#-설치)를 보세요.
62
140
 
63
141
  ### pnpm 설정 (권장)
64
142
 
@@ -95,6 +173,12 @@ pnpm run dev
95
173
  pnpm run build
96
174
  ```
97
175
 
176
+ ### 테스트
177
+
178
+ ```bash
179
+ pnpm test
180
+ ```
181
+
98
182
  ### 린트 & 타입 체크
99
183
 
100
184
  ```bash
@@ -114,16 +198,16 @@ pnpm run preview
114
198
 
115
199
  - `main`으로 향하는 PR마다 AI가 변경 내용을 요약한 changeset 파일을 초안으로 작성합니다.
116
200
  - `main`에 changeset들이 쌓이면 "Version Packages" PR이 `package.json`의 버전을 승격시키고 `CHANGELOG.md`를 정리합니다.
117
- - 이 PR을 머지하면 빌드, 태그 생성, (이 패키지가 공개로 전환되면) npm 배포가 실행됩니다.
201
+ - 이 PR을 머지하면 빌드, 태그 생성, npm 배포가 실행됩니다.
118
202
 
119
203
  CI 워크플로우:
120
204
 
121
205
  - `changeset-draft.yml`: `main` 대상 PR이 열리거나 갱신될 때 AI가 changeset 초안을 작성
122
206
  - `version.yml`: changeset이 쌓이면 "Version Packages" PR을 열거나 갱신
123
- - `publish.yml`: `main` 머지 시 버전이 미태그 상태면 빌드/(공개 패키지면 배포)/태그/GitHub Release 생성
207
+ - `publish.yml`: `main` 머지 시 버전이 미태그 상태면 빌드/배포/태그/GitHub Release 생성
124
208
  - `release.yml`: 기존 태그에 대한 GitHub Release를 수동(`workflow_dispatch`)으로 재생성하는 백업 유틸리티
125
209
  - Docusaurus 문서 사이트는 `website/`에서 빌드되며 Vercel로 배포됩니다(`vercel.json` 참고).
126
210
 
127
211
  ## 📄 라이선스
128
212
 
129
- MIT License
213
+ [MIT License](./LICENSE) — Copyright (c) 2026 jbpark
package/README.md CHANGED
@@ -12,20 +12,25 @@ An interactive editor for building UIs with real-time preview and drag‑and‑d
12
12
  live-editor/
13
13
  ├─ src/
14
14
  │ ├─ components/
15
- │ │ ├─ Context/ # Global state management
16
- │ │ ├─ Dnd/ # Drag-and-drop system with editing panels
17
- │ │ ├─ Editor/ # Code editor
18
- │ │ ├─ Error/ # Error boundary
19
- │ │ ├─ Frame/ # iframe/shadow-DOM preview isolation
20
- │ │ └─ Preview/ # Isolated preview runtime
15
+ │ │ ├─ context/ # Global state management
16
+ │ │ ├─ dnd/ # Drag-and-drop system with editing panels
17
+ │ │ │ └─ panel/ # Property panel field editors
18
+ │ │ ├─ editor/ # CodeMirror code editor
19
+ │ │ ├─ error/ # Error boundary
20
+ │ │ ├─ frame/ # iframe/shadow-DOM preview isolation
21
+ │ │ └─ preview/ # Isolated preview runtime
21
22
  │ ├─ pages/
22
- │ │ └─ Editor/ # Local development editor (editor + DnD toggle)
23
- │ ├─ utils/ast/ # AST manipulation & code generation
24
- │ ├─ constants/ # Constants and configurations
25
- │ ├─ types/ # TypeScript type definitions
26
- └─ main.tsx # Local development app entry
27
- ├─ demos/ # Standalone iframe demos for the documentation
28
- ├─ website/ # Docusaurus documentation site
23
+ │ │ └─ editor/ # Local development editor (editor + DnD toggle)
24
+ │ ├─ utils/
25
+ ├─ ast/ # AST manipulation & code generation
26
+ ├─ tailwind/ # Tailwind theme helpers
27
+ │ ├─ cache.ts # Bounded LRU cache
28
+ │ │ └─ selection.ts # Multi-select helpers
29
+ ├─ constants/ # Constants and configurations
30
+ │ ├─ types/ # TypeScript type definitions
31
+ │ └─ main.tsx # Local development app entry
32
+ ├─ demos/ # Standalone iframe demos for the documentation
33
+ ├─ website/ # Docusaurus documentation site
29
34
  └─ package.json
30
35
  ```
31
36
 
@@ -38,6 +43,76 @@ live-editor/
38
43
  - **Preview runtime**: Renders compiled output inside an iframe for DOM/CSS isolation (not a security sandbox — see [Security Notes](#-security-notes)).
39
44
  - **Robust drag-and-drop**: Powered by `@dnd-kit` for smooth sorting and positioning.
40
45
 
46
+ ## 📦 Installation
47
+
48
+ ```bash
49
+ pnpm add @jbpark/live-editor react react-dom
50
+ ```
51
+
52
+ `react` and `react-dom` (>= 19) are peer dependencies. `prettier` (>= 3) is an
53
+ optional peer — install it too if you want the editor's format-on-save; without
54
+ it the editor still works and simply skips formatting.
55
+
56
+ ## 🧑‍💻 Usage
57
+
58
+ Import the stylesheet once near your app root — it is **required** and is not
59
+ imported by the JS entry:
60
+
61
+ ```tsx
62
+ import { useState } from 'react';
63
+
64
+ import Live from '@jbpark/live-editor';
65
+ import '@jbpark/live-editor/style.css';
66
+
67
+ // required — not imported by the JS entry
68
+
69
+ const SAMPLE = `
70
+ import * as ui from 'ui-kit';
71
+
72
+ const App = () => (
73
+ <div className="p-6 space-y-2">
74
+ <ui.Typography.Title level={3}>Hello</ui.Typography.Title>
75
+ <ui.Button type="primary">Edit me</ui.Button>
76
+ </div>
77
+ );
78
+
79
+ export default App;
80
+ `;
81
+
82
+ export default function Example() {
83
+ const [code, setCode] = useState(SAMPLE);
84
+
85
+ return (
86
+ <Live>
87
+ <Live.Editor value={code} onChange={setCode} />
88
+ <Live.Preview showError frame={{ mode: 'iframe', syncStyle: true }} />
89
+ </Live>
90
+ );
91
+ }
92
+ ```
93
+
94
+ See the [documentation site](https://live-editor-lab.vercel.app) for the full
95
+ guide (how Tailwind reaches the preview, custom panels, and more).
96
+
97
+ ## 🧩 Entry points
98
+
99
+ The package ships subpath exports so a consumer who needs only one feature area
100
+ can avoid pulling in the rest (e.g. no CodeMirror in a preview-only build) — see
101
+ [#194](https://github.com/pjb0811/live-editor/issues/194):
102
+
103
+ | Import | Contains |
104
+ | ------------------------------------ | ------------------------------------------- |
105
+ | `@jbpark/live-editor` | Everything (`Live` provider + all surfaces) |
106
+ | `@jbpark/live-editor/provider` | The shared editing context provider only |
107
+ | `@jbpark/live-editor/dnd` | Drag-and-drop canvas + property panel |
108
+ | `@jbpark/live-editor/editor` | CodeMirror code editor |
109
+ | `@jbpark/live-editor/preview` | Isolated preview runtime |
110
+ | `@jbpark/live-editor/error` | Error boundary |
111
+ | `@jbpark/live-editor/utils` | Compile/section helpers |
112
+ | `@jbpark/live-editor/utils/ast` | AST manipulation & code generation |
113
+ | `@jbpark/live-editor/utils/tailwind` | Tailwind theme helpers |
114
+ | `@jbpark/live-editor/style.css` | Compiled stylesheet (required) |
115
+
41
116
  ## 🔒 Security Notes
42
117
 
43
118
  - The `sandbox` prop on the preview `<iframe>` (`src/components/frame/iframe.tsx`) is **not a security boundary**. Compiled preview code is executed via `new Function(...)` in the host page's own JS realm (`compileModule` in `src/utils/index.ts`); only the resulting React elements are portaled into the iframe's `contentDocument` for DOM/CSS rendering. The iframe itself never evaluates user code.
@@ -58,7 +133,10 @@ live-editor/
58
133
  - Node.js: 20.x or higher
59
134
  - **pnpm**: 10.x or higher (managed via [Corepack](https://nodejs.org/api/corepack.html))
60
135
 
61
- ## 🚀 Getting Started
136
+ ## 🚀 Development (this repo)
137
+
138
+ > Working on Live Editor itself. To _use_ the package in your app, see
139
+ > [Installation](#-installation) above.
62
140
 
63
141
  ### pnpm Setup (Recommended)
64
142
 
@@ -96,6 +174,12 @@ feature demos live in `website/`.
96
174
  pnpm run build
97
175
  ```
98
176
 
177
+ ### Test
178
+
179
+ ```bash
180
+ pnpm test
181
+ ```
182
+
99
183
  ### Lint & Type Check
100
184
 
101
185
  ```bash
@@ -115,17 +199,17 @@ Releases are fully automated via [changesets](https://github.com/changesets/chan
115
199
 
116
200
  - Each PR against `main` gets an AI-drafted changeset file describing its change.
117
201
  - Once changesets accumulate on `main`, a "Version Packages" PR bumps `package.json`'s version and consolidates `CHANGELOG.md`.
118
- - Merging that PR builds, tags the release, and (once this package is made public) publishes to npm.
202
+ - Merging that PR builds, tags the release, and publishes to npm.
119
203
 
120
204
  CI workflows:
121
205
 
122
206
  - `changeset-draft.yml`: Drafts an AI-generated changeset on PR open/sync against `main`.
123
207
  - `version.yml`: Opens/updates the "Version Packages" PR once changesets accumulate.
124
- - `publish.yml`: Builds/(publishes if public)/tags/creates the GitHub Release on merge to `main` when the version is untagged.
208
+ - `publish.yml`: Builds/publishes/tags/creates the GitHub Release on merge to `main` when the version is untagged.
125
209
  - `release.yml`: Manual `workflow_dispatch` fallback to (re)create a GitHub Release for an existing tag.
126
210
  - The Docusaurus documentation site is built from `website/` and deployed via
127
211
  Vercel (see `vercel.json`).
128
212
 
129
213
  ## 📄 License
130
214
 
131
- MIT License
215
+ [MIT License](./LICENSE) — Copyright (c) 2026 jbpark
@@ -1,2 +1,2 @@
1
- import { a as ICON_OPTIONS, c as PanelRenderData, d as DraggableItemDragState, f as DraggableItemProps, i as ICON_MAP, l as Props, n as Panel, o as PaletteRenderData, r as PanelProps, s as PanelBinding, t as Dnd, u as DraggableItem } from "../index-9bvWkK07.js";
2
- export { Panel as DefaultPanel, DraggableItem, type DraggableItemDragState, type DraggableItemProps, ICON_MAP, ICON_OPTIONS, type PaletteRenderData, type PanelBinding, type PanelProps, type PanelRenderData, type Props, Dnd as default };
1
+ import { S as DraggableItemProps, _ as PanelNodeChange, a as ItemsEditorNestedElement, b as DraggableItem, c as useItemsEditor, d as ICON_MAP, f as ICON_OPTIONS, g as PanelBinding, h as PaletteRenderData, i as ItemsEditorItem, l as Panel, m as FieldProps, n as ItemsEditor, o as ItemsEditorNestedGroup, p as Field, r as ItemsEditorActions, s as ItemsEditorOptions, t as Dnd, u as PanelProps, v as PanelRenderData, x as DraggableItemDragState, y as Props } from "../index-DYm4nsej.js";
2
+ export { Panel as DefaultPanel, DraggableItem, type DraggableItemDragState, type DraggableItemProps, Field, type FieldProps, ICON_MAP, ICON_OPTIONS, type ItemsEditor, type ItemsEditorActions, type ItemsEditorItem, type ItemsEditorNestedElement, type ItemsEditorNestedGroup, type ItemsEditorOptions, type PaletteRenderData, type PanelBinding, type PanelNodeChange, type PanelProps, type PanelRenderData, type Props, Dnd as default, useItemsEditor };
package/dist/dnd/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as DraggableItem, i as ICON_OPTIONS, n as Panel, r as ICON_MAP, t as Dnd } from "../dnd-C1YGcp4k.js";
2
- export { Panel as DefaultPanel, DraggableItem, ICON_MAP, ICON_OPTIONS, Dnd as default };
1
+ import { a as ICON_OPTIONS, i as ICON_MAP, n as Panel, o as useItemsEditor, r as Field, s as DraggableItem, t as Dnd } from "../dnd-DRivgZdt.js";
2
+ export { Panel as DefaultPanel, DraggableItem, Field, ICON_MAP, ICON_OPTIONS, Dnd as default, useItemsEditor };