@wipco/sdui-editor 0.1.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.
@@ -0,0 +1,147 @@
1
+ /*
2
+ * 편집기 스타일 — 라이브러리 토큰(wp-*) 위에 얹는다.
3
+ *
4
+ * 예전 관리자 앱의 스타일시트에서 왔지만 두 가지가 달라졌다:
5
+ *
6
+ * 1. **전역 리셋을 걷어냈다.** 이 CSS는 소비 프로젝트의 페이지 안으로 들어간다 —
7
+ * `* { box-sizing }`이나 `body { font-family }`를 여기서 선언하면 편집기를 한 번
8
+ * 마운트했다는 이유로 그 프로젝트 전체의 타이포그래피가 바뀐다.
9
+ * 2. **모든 클래스에 `sdui-editor-` 접두를 붙였다.** `.editor-toolbar`·`.help-panel`
10
+ * 같은 흔한 이름은 소비 프로젝트와 부딪칠 여지가 크다.
11
+ *
12
+ * 높이: 편집기는 부모가 준 높이를 채우되(`height: 100%`), 부모 높이가 auto인
13
+ * 평범한 문서 흐름에 놓여도 편집·미리보기 창이 찌부러지지 않도록 분할 영역에
14
+ * 최소 높이를 준다.
15
+ */
16
+
17
+ .sdui-editor {
18
+ display: flex;
19
+ flex-direction: column;
20
+ min-height: 0;
21
+ height: 100%;
22
+ color: var(--wp-text-default);
23
+ font-size: 13px;
24
+ }
25
+ .sdui-editor *,
26
+ .sdui-editor *::before,
27
+ .sdui-editor *::after { box-sizing: border-box; }
28
+
29
+ .sdui-editor-center {
30
+ display: flex; align-items: center; justify-content: center;
31
+ padding: 48px 0;
32
+ }
33
+
34
+ /* ---------- 편집기 자체 헤더 (chrome=false면 안 그린다) ---------- */
35
+ .sdui-editor-chrome {
36
+ display: flex; align-items: center; gap: 12px;
37
+ height: 44px; padding: 0 16px; flex: none;
38
+ background: var(--wp-chrome-bg); color: var(--wp-chrome-fg);
39
+ }
40
+ .sdui-editor-chrome__title { font-size: 13px; font-weight: 700; letter-spacing: 0.01em; }
41
+
42
+ /* ---------- 목록 화면 ---------- */
43
+ .sdui-editor-page {
44
+ width: 100%; max-width: 1080px; margin: 0 auto;
45
+ padding: 28px 24px 48px;
46
+ display: flex; flex-direction: column; gap: var(--wp-space-4);
47
+ }
48
+ .sdui-editor-list-toolbar {
49
+ display: flex; align-items: center; gap: 12px;
50
+ padding: 12px 16px; border-bottom: 1px solid var(--wp-border-subtle);
51
+ }
52
+ .sdui-editor-list-toolbar .wp-inputwrap { max-width: 320px; }
53
+
54
+ /* 저장소 제약 목록 — Alert 안에 들어가므로 여백만 정리한다 */
55
+ .sdui-editor-limitations { margin: 4px 0 0; padding-left: 18px; }
56
+ .sdui-editor-limitations li { margin: 2px 0; }
57
+
58
+ /* ---------- 편집 화면 ---------- */
59
+ .sdui-editor-layout { flex: 1; min-height: 0; display: flex; flex-direction: column; }
60
+ .sdui-editor-toolbar {
61
+ display: flex; align-items: center; gap: 8px; flex: none;
62
+ padding: 8px 12px; background: var(--wp-surface-card);
63
+ border-bottom: 1px solid var(--wp-border-subtle);
64
+ flex-wrap: wrap;
65
+ }
66
+ .sdui-editor-toolbar__id { font-weight: 700; color: var(--wp-text-brand); }
67
+ .sdui-editor-banner { padding: 8px 12px 0; }
68
+ .sdui-editor-split {
69
+ flex: 1; display: flex;
70
+ /* 부모 높이가 auto여도 편집·미리보기가 쓸 만한 크기를 갖게 한다 */
71
+ min-height: clamp(480px, 70vh, 900px);
72
+ }
73
+ .sdui-editor-pane {
74
+ width: 46%; min-width: 380px; display: flex; flex-direction: column; min-height: 0;
75
+ border-right: 1px solid var(--wp-border-subtle); background: var(--wp-surface-card);
76
+ }
77
+ .sdui-editor-json { flex: 1; min-height: 0; overflow: hidden; }
78
+ .sdui-editor-json .cm-editor { height: 100%; }
79
+ .sdui-editor-issues {
80
+ flex: none; max-height: 160px; overflow-y: auto;
81
+ border-top: 1px solid var(--wp-border-subtle); background: var(--wp-slate-25);
82
+ padding: 8px 12px; display: flex; flex-direction: column; gap: 4px;
83
+ }
84
+ .sdui-editor-issue { font-size: 12px; color: var(--wp-text-warning); display: flex; gap: 8px; align-items: baseline; }
85
+ .sdui-editor-issue .wp-mono-xs { color: var(--wp-text-subtle); flex: none; }
86
+ .sdui-editor-issue--error { color: var(--wp-text-danger); }
87
+
88
+ .sdui-editor-preview { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 0; }
89
+ .sdui-editor-preview__head {
90
+ flex: none; display: flex; align-items: center; gap: 12px;
91
+ padding: 8px 16px; border-bottom: 1px solid var(--wp-border-subtle);
92
+ background: var(--wp-slate-25);
93
+ }
94
+ .sdui-editor-preview__notice { font-size: 12px; color: var(--wp-text-info); }
95
+ .sdui-editor-preview__body { flex: 1; overflow-y: auto; padding: 24px; position: relative; }
96
+ .sdui-editor-preview__body .sdui-root { display: flex; flex-direction: column; gap: var(--wp-space-4); }
97
+
98
+ /* ---------- 도움말 패널 ---------- */
99
+ .sdui-editor-help {
100
+ width: 340px; flex: none; display: flex; flex-direction: column; min-height: 0;
101
+ border-left: 1px solid var(--wp-border-subtle); background: var(--wp-surface-card);
102
+ }
103
+ .sdui-editor-help__head {
104
+ flex: none; display: flex; align-items: center; justify-content: space-between;
105
+ padding: 10px 14px; border-bottom: 1px solid var(--wp-border-subtle);
106
+ }
107
+ .sdui-editor-help__body {
108
+ flex: 1; overflow-y: auto; padding: 14px;
109
+ display: flex; flex-direction: column; gap: 18px;
110
+ }
111
+ .sdui-editor-help__body section { display: flex; flex-direction: column; gap: 8px; }
112
+ .sdui-editor-help__code {
113
+ margin: 0; padding: 10px; font-size: 11px; line-height: 1.5;
114
+ font-family: 'JetBrains Mono', ui-monospace, monospace;
115
+ background: var(--wp-slate-50); border: 1px solid var(--wp-border-subtle);
116
+ border-radius: var(--wp-radius-md); overflow-x: auto; white-space: pre;
117
+ }
118
+ .sdui-editor-help__dl { margin: 0; display: flex; flex-direction: column; gap: 7px; }
119
+ .sdui-editor-help__dl dt { margin: 0; }
120
+ .sdui-editor-help__dl dt code { font-size: 11px; font-family: 'JetBrains Mono', ui-monospace, monospace; color: var(--wp-text-brand); }
121
+ .sdui-editor-help__dl dd { margin: 1px 0 0; font-size: 12px; color: var(--wp-text-muted); }
122
+ .sdui-editor-help__chips { display: flex; flex-wrap: wrap; gap: 4px; }
123
+ .sdui-editor-help__chip {
124
+ font-size: 11px; font-family: 'JetBrains Mono', ui-monospace, monospace;
125
+ background: var(--wp-slate-100); border-radius: var(--wp-radius-sm); padding: 2px 6px;
126
+ }
127
+
128
+ /* ---------- 뷰어 ---------- */
129
+ .sdui-editor-viewer { flex: 1; min-height: 0; display: flex; flex-direction: column; }
130
+ .sdui-editor-viewer__bar {
131
+ flex: none; display: flex; align-items: center; gap: 12px;
132
+ padding: 8px 16px;
133
+ background: var(--wp-surface-card);
134
+ border-bottom: 1px solid var(--wp-border-subtle);
135
+ }
136
+ .sdui-editor-viewer__id { color: var(--wp-text-subtle); }
137
+ .sdui-editor-viewer__body { flex: 1; width: 100%; max-width: 1080px; margin: 0 auto; padding: 28px 24px 48px; }
138
+ .sdui-editor-viewer__body .sdui-root { display: flex; flex-direction: column; gap: var(--wp-space-4); }
139
+
140
+ @media (max-width: 900px) {
141
+ .sdui-editor-split { flex-direction: column; }
142
+ .sdui-editor-pane {
143
+ width: 100%; min-width: 0; height: 50%;
144
+ border-right: none; border-bottom: 1px solid var(--wp-border-subtle);
145
+ }
146
+ .sdui-editor-help { position: fixed; right: 0; top: 0; bottom: 0; box-shadow: var(--wp-shadow-lg); z-index: 50; }
147
+ }
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@wipco/sdui-editor",
3
+ "version": "0.1.0",
4
+ "description": "SDUI 페이지 스펙 편집기 — 소비 프로젝트가 자기 라우트에 마운트하는 React 컴포넌트",
5
+ "keywords": [
6
+ "sdui",
7
+ "server-driven-ui",
8
+ "react",
9
+ "editor"
10
+ ],
11
+ "author": "wipco-dev",
12
+ "license": "UNLICENSED",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/wipco-dev/wipco-sdui.git",
16
+ "directory": "packages/sdui-editor"
17
+ },
18
+ "homepage": "https://github.com/wipco-dev/wipco-sdui#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/wipco-dev/wipco-sdui/issues"
21
+ },
22
+ "type": "module",
23
+ "main": "./dist/index.js",
24
+ "module": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "default": "./dist/index.js"
30
+ },
31
+ "./styles.css": "./dist/styles.css",
32
+ "./package.json": "./package.json"
33
+ },
34
+ "sideEffects": [
35
+ "**/*.css"
36
+ ],
37
+ "files": [
38
+ "dist"
39
+ ],
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "registry": "https://registry.npmjs.org/"
43
+ },
44
+ "scripts": {
45
+ "build": "tsup && cp src/styles.css dist/styles.css",
46
+ "dev": "tsup --watch",
47
+ "typecheck": "tsc --noEmit",
48
+ "prepack": "pnpm run build"
49
+ },
50
+ "dependencies": {
51
+ "@codemirror/commands": "^6.8.0",
52
+ "@codemirror/lang-json": "^6.0.1",
53
+ "@codemirror/state": "^6.5.0",
54
+ "@codemirror/view": "^6.36.0",
55
+ "codemirror": "^6.0.1"
56
+ },
57
+ "peerDependencies": {
58
+ "@wipco/sdui": "^0.1.0",
59
+ "react": ">=18",
60
+ "react-dom": ">=18"
61
+ },
62
+ "devDependencies": {
63
+ "@types/react": "^19.0.0",
64
+ "@types/react-dom": "^19.0.0",
65
+ "@wipco/sdui": "^0.1.0",
66
+ "tsup": "^8.5.0",
67
+ "typescript": "^5.7.0"
68
+ }
69
+ }