@hashrock/ono-visual-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.
- package/LICENSE +21 -0
- package/README.md +121 -0
- package/dist/core.js +35 -0
- package/dist/index.js +574 -0
- package/dist/style.css +1 -0
- package/dist/uno-controls-CopUGd4g.js +451 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 hashrock
|
|
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.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# @hashrock/ono-visual-editor
|
|
2
|
+
|
|
3
|
+
Ono用の簡易ビジュアルWebエディタを、**Reactコンポーネント1個のライブラリ**として提供します。JSXを編集し、Onoのブラウザコンパイラ(sucrase + UnoCSS、Web Worker上)でレンダリングしたプレビューを見ながら、要素をクリックしてインスペクタから編集できます。
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @hashrock/ono-visual-editor @hashrock/ono react react-dom
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
import { useState } from 'react';
|
|
11
|
+
import { VisualEditor } from '@hashrock/ono-visual-editor';
|
|
12
|
+
import '@hashrock/ono-visual-editor/style.css';
|
|
13
|
+
|
|
14
|
+
const files = {
|
|
15
|
+
'index.jsx': `export default function App() {
|
|
16
|
+
return <h1 class="text-3xl font-bold text-emerald-600">Hello, Ono!</h1>;
|
|
17
|
+
}
|
|
18
|
+
`,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export function App() {
|
|
22
|
+
const [project, setProject] = useState(files);
|
|
23
|
+
// 親要素に高さを与えてください(エディタはコンテナいっぱいに広がります)
|
|
24
|
+
return (
|
|
25
|
+
<div style={{ height: '100vh' }}>
|
|
26
|
+
<VisualEditor files={project} entry="index.jsx" onChange={setProject} />
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
コンパイラのWeb Workerはビルド時にインライン化されているため、利用側でworkerやアセットの設定は不要です。スタイルは `.ono-ve` 配下にスコープされており、`style.css` を1回importするだけです。
|
|
33
|
+
|
|
34
|
+
## できること
|
|
35
|
+
|
|
36
|
+
- プレビュー上の要素をクリックして選択(ソース側の該当範囲もハイライト)
|
|
37
|
+
- `class` のGUI編集:クラスはチップ表示(クリックで削除、入力欄で追加)。余白・サイズ・タイポグラフィ・色(パレット+シェード)・角丸・ボーダー・影・レイアウトはセレクトやスウォッチで切り替え。`sm:` や `hover:` 付きなどGUIが扱わないクラスはチップのまま保持されます
|
|
38
|
+
- テキスト / その他の文字列属性の編集
|
|
39
|
+
- 要素の削除・複製・親要素の選択
|
|
40
|
+
- **ドラッグ&ドロップで移動**:プレビュー上で要素を掴んで他の要素の前後にドロップ(横並びなら左右、縦積みなら上下にドロップ線が出ます)。コンポーネントのルート(例: `Card` の外側の div)を掴むと、親ファイル側の `<Card>` 使用箇所が移動します
|
|
41
|
+
- **挿入パレット**:プレビュー上部のタイル(Heading / Paragraph / Button / Link / Box / Row / Image / List / Input / Divider)をプレビューへ**ドラッグ&ドロップ**して要素の前後に挿入、またはクリックで選択要素の直後に挿入。挿入した要素はそのまま選択されます
|
|
42
|
+
- Undo / Redo(ボタン、または ⌘/Ctrl+Z, ⌘/Ctrl+Shift+Z / ⌘/Ctrl+Y。テキスト入力中はブラウザ標準の Undo が優先)
|
|
43
|
+
- 複数ファイル(`components/*.jsx` からのimport)対応。コンポーネント内部の要素を選択すると自動でそのファイルのタブに切り替わります
|
|
44
|
+
- 同じコンポーネントが複数回使われている場合も、クリックしたインスタンスに枠が付きます(インスペクタに「Instance n of N」を表示。編集はソース側なので全インスタンスに反映)
|
|
45
|
+
|
|
46
|
+
ビジュアル編集は全てJSXソースへのテキスト編集として反映されるため、フォーマットは保持されます。
|
|
47
|
+
|
|
48
|
+
## Props
|
|
49
|
+
|
|
50
|
+
| prop | 型 | 既定値 | 説明 |
|
|
51
|
+
|---|---|---|---|
|
|
52
|
+
| `files` | `Record<string, string>` | 同梱のサンプル | ファイル名 → ソース。**別のオブジェクト**を渡すとその内容で読み込み直します(`onChange` で受け取ったオブジェクトを渡し戻しても再読み込みは起きません) |
|
|
53
|
+
| `entry` | `string` | `'index.jsx'` | プレビューのエントリポイント |
|
|
54
|
+
| `onChange` | `(files) => void` | – | 編集のたびに全ファイルを通知 |
|
|
55
|
+
| `onSelect` | `(sel \| null) => void` | – | 選択変更時に `{ filename, index, tag }` を通知 |
|
|
56
|
+
| `snippets` | `Snippet[]` | `DEFAULT_SNIPPETS` | 挿入パレット(`{ label, icon, code }`) |
|
|
57
|
+
| `createWorker` | `() => Worker` | 同梱のコンパイラWorker | コンパイラWorkerを差し替える |
|
|
58
|
+
| `header` | `boolean` | `true` | 上部ツールバーの表示 |
|
|
59
|
+
| `title` / `tagline` | `ReactNode` | `'Ono Visual Editor'` ほか | ツールバーの見出し |
|
|
60
|
+
| `actions` | `ReactNode` | – | Undo / Redo / Run の前に差し込む追加ボタン |
|
|
61
|
+
| `statusBar` | `boolean` | `true` | 下部ステータス行の表示 |
|
|
62
|
+
| `globalShortcuts` | `boolean` | `true` | `window` にキーボードショートカットを登録。`false` にするとプレビュー内のみ |
|
|
63
|
+
| `className` / `style` | | – | ルート要素に付与 |
|
|
64
|
+
|
|
65
|
+
`files` を一度だけ渡せば非制御コンポーネントとして、新しいオブジェクトを渡し直せばプロジェクトの切り替え・リセットとして使えます(`demo/App.jsx` の "Reset example" が後者の例)。
|
|
66
|
+
|
|
67
|
+
## ヘッドレスコア
|
|
68
|
+
|
|
69
|
+
React にもDOMにも依存しない編集ロジックは `@hashrock/ono-visual-editor/core` から使えます(Nodeでも動きます)。独自UIを作る場合はこちら。
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
import {
|
|
73
|
+
parseElements, setAttr, setText, removeElement, duplicateElement, moveElementTo, insertSnippet, instrument,
|
|
74
|
+
reducer, initialState, elementsOf, // 編集コマンドの reducer(undo/redo込み)
|
|
75
|
+
GROUPS, classList, readValue, writeValue, // UnoCSSコントロール
|
|
76
|
+
} from '@hashrock/ono-visual-editor/core';
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## 構成
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
src/
|
|
83
|
+
index.js ライブラリのエントリ(VisualEditor / DEFAULT_SNIPPETS / EXAMPLE_FILES)
|
|
84
|
+
core.js ヘッドレスコアのエントリ
|
|
85
|
+
VisualEditor.jsx DOM 由来の情報をコマンドに変換して dispatch、コンパイルの副作用
|
|
86
|
+
editor.js 純粋な reducer:編集コマンド(setAttr / setText / remove / duplicate / move / insert)と select / setSource / undo / redo / load
|
|
87
|
+
useCompiler.js コンパイラ Worker のフック(デバウンス・古い応答の破棄)
|
|
88
|
+
jsx-source.js JSX ソースモデル(純粋ロジック、Node でテスト)
|
|
89
|
+
uno-controls.js UnoCSS コントロール定義(純粋ロジック、Node でテスト)
|
|
90
|
+
compiler.worker.js Ono のブラウザコンパイラを動かす Web Worker(ビルド時にインライン化)
|
|
91
|
+
snippets.js 既定の挿入パレット
|
|
92
|
+
example.js 同梱サンプルプロジェクト
|
|
93
|
+
styles.css `.ono-ve` 配下にスコープしたスタイル
|
|
94
|
+
components/
|
|
95
|
+
Editor.jsx タブ + ファイルごとの textarea
|
|
96
|
+
Preview.jsx iframe への描画、クリック/ホバー/ショートカット
|
|
97
|
+
Inspector.jsx 選択要素の属性・アクション
|
|
98
|
+
Palette.jsx 挿入パレット(HTML5 DnD でプレビューへドロップ)
|
|
99
|
+
ClassEditor.jsx クラスのチップ + GUI コントロール + カラーピッカー
|
|
100
|
+
CommitInput.jsx Enter / blur で確定する入力
|
|
101
|
+
demo/ エディタをホストするデモアプリ(Vite)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 仕組み
|
|
105
|
+
|
|
106
|
+
状態は `useReducer` で一元管理し、すべての編集は `{ type, target: { filename, index }, ... }` 形式のコマンドとして reducer に渡されます。reducer は該当ファイルのソースを書き換え、履歴(past / future)と次に選択すべき要素を決め、`compile: 'now' | 'soon'` でコンパイルを促します。UI コンポーネントはコマンドを発行するだけで、ソース編集関数を直接呼びません。
|
|
107
|
+
|
|
108
|
+
ドラッグ移動は `moveElementTo` がソース上で要素を切り出して別の要素の前後に挿入します(同一ファイル内のみ。インデントは移動先に合わせます)。
|
|
109
|
+
|
|
110
|
+
`uno-controls.js` が「コントロール=クラスリスト内の1スロット」(例: padding-x、text color)を定義し、現在値の読み取りとその場での置換を行います。
|
|
111
|
+
|
|
112
|
+
`jsx-source.js` がsucraseのトークナイザで各ファイルのJSX要素の位置を求め、ホスト要素(小文字タグ)に `data-ono-id="<file>#<index>"` を付与してからOnoでレンダリングします。プレビューのDOMからこのIDを辿り、元のソース範囲を書き換えます。
|
|
113
|
+
|
|
114
|
+
## 開発
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
pnpm dev # デモアプリの開発サーバー(src を直接読むのでHMRが効く)
|
|
118
|
+
pnpm build # ライブラリを dist/ にビルド
|
|
119
|
+
pnpm build:demo # デモアプリを demo-dist/ にビルド
|
|
120
|
+
pnpm test # ソース編集ロジックのテスト
|
|
121
|
+
```
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { C as e, z as t, E as r, G as i, H as l, I as n, S, o, h as m, u as p, y as E, j as d, k as A, f as C, g as T, l as c, d as u, e as f, i as I, c as O, m as h, x, p as D, v as H, n as L, r as R, b as _, a as g, s as v, q as w, t as U, w as G } from "./uno-controls-CopUGd4g.js";
|
|
2
|
+
export {
|
|
3
|
+
e as CLASS_ATTRS,
|
|
4
|
+
t as COLOR_HUES,
|
|
5
|
+
r as EDIT_COMMANDS,
|
|
6
|
+
i as GROUPS,
|
|
7
|
+
l as HUES,
|
|
8
|
+
n as ID_ATTR,
|
|
9
|
+
S as SCALE,
|
|
10
|
+
o as SHADES,
|
|
11
|
+
m as appendChild,
|
|
12
|
+
p as classList,
|
|
13
|
+
E as colorClass,
|
|
14
|
+
d as duplicateElement,
|
|
15
|
+
A as elementsOf,
|
|
16
|
+
C as findAttr,
|
|
17
|
+
T as getText,
|
|
18
|
+
c as initialState,
|
|
19
|
+
u as insertAfter,
|
|
20
|
+
f as insertSnippet,
|
|
21
|
+
I as instrument,
|
|
22
|
+
O as isWithin,
|
|
23
|
+
h as moveElementTo,
|
|
24
|
+
x as parseColor,
|
|
25
|
+
D as parseElements,
|
|
26
|
+
H as readValue,
|
|
27
|
+
L as reducer,
|
|
28
|
+
R as removeElement,
|
|
29
|
+
_ as setAttr,
|
|
30
|
+
g as setText,
|
|
31
|
+
v as splitId,
|
|
32
|
+
w as swatchColor,
|
|
33
|
+
U as targetId,
|
|
34
|
+
G as writeValue
|
|
35
|
+
};
|