@bladeberg/editor 0.2.0 → 0.2.2
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/README.md +113 -637
- package/README.npm.md +208 -0
- package/dist-npm/bladeberg.js +206 -193
- package/dist-npm/isolated-block-editor.js +9 -0
- package/dist-npm/style.css +2327 -3113
- package/package.json +4 -6
- package/dist-npm/isolated-block-editor-FqFbPhep.js +0 -61842
package/README.npm.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# @bladeberg/editor
|
|
2
|
+
|
|
3
|
+
**Gutenberg, standalone.** No WordPress. No Laravel. Just the block editor in your React app.
|
|
4
|
+
|
|
5
|
+
BladeBerg wraps [`@automattic/isolated-block-editor`](https://github.com/Automattic/isolated-block-editor) — the same pre-built browser bundle Automattic uses to run Gutenberg outside of wp-admin — and ships it as a lazy-loaded npm package. You get paragraphs, headings, images, columns, embeds, the whole core block library, without installing a single `@wordpress/*` package yourself.
|
|
6
|
+
|
|
7
|
+
> Using Laravel? See the full [BladeBerg docs](https://github.com/BladeBerg/bladeberg#readme) for the Composer package, Blade components, PHP rendering, and media API.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @bladeberg/editor react react-dom
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
That's it. The Gutenberg runtime is **bundled inside the package** — you won't hit WordPress dependency hell.
|
|
18
|
+
|
|
19
|
+
**Requirements:** React 18 or 19, a modern browser, and a bundler that supports ESM (`import`).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Quick start
|
|
24
|
+
|
|
25
|
+
```jsx
|
|
26
|
+
import { createEditor } from '@bladeberg/editor';
|
|
27
|
+
import '@bladeberg/editor/style.css';
|
|
28
|
+
|
|
29
|
+
const editor = await createEditor({
|
|
30
|
+
target: '#editor', // selector or DOM element
|
|
31
|
+
value: savedContent, // optional — existing block HTML
|
|
32
|
+
blockPrefix: 'bb', // prefix in stored content (default: bb)
|
|
33
|
+
onChange: (html) => {
|
|
34
|
+
draft = html; // live updates (optional)
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// When the user saves:
|
|
39
|
+
await fetch('/api/posts/1', {
|
|
40
|
+
method: 'PUT',
|
|
41
|
+
headers: { 'Content-Type': 'application/json' },
|
|
42
|
+
body: JSON.stringify({ content: editor.getContent() }),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// On route change / unmount:
|
|
46
|
+
editor.destroy();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`createEditor()` is async — it lazy-loads the Gutenberg runtime on first call (~2 MB, cached after that).
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## What you get
|
|
54
|
+
|
|
55
|
+
| Feature | Details |
|
|
56
|
+
|---------|---------|
|
|
57
|
+
| **Full core blocks** | Paragraph, heading, list, image, quote, columns, embeds, etc. |
|
|
58
|
+
| **Portable HTML** | Content serializes to block comments: `<!-- bb:paragraph -->…` |
|
|
59
|
+
| **Branded prefix** | Default `bb:` instead of WordPress's `wp:` — configurable |
|
|
60
|
+
| **Right-click menu** | Block Options (Copy, Duplicate, Remove, …) restored |
|
|
61
|
+
| **Media upload** | Optional — wire to your own API (see below) |
|
|
62
|
+
| **Zero WordPress deps** | Runtime is pre-built and shipped in the tarball |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## API
|
|
67
|
+
|
|
68
|
+
### `createEditor(options)`
|
|
69
|
+
|
|
70
|
+
| Option | Type | Default | Description |
|
|
71
|
+
|--------|------|---------|-------------|
|
|
72
|
+
| `target` | `string \| Element` | *(required)* | CSS selector or element. A `<textarea>` is mounted directly; any other element gets a hidden textarea appended. |
|
|
73
|
+
| `value` | `string` | `''` | Initial block HTML (your configured prefix). |
|
|
74
|
+
| `blockPrefix` | `string` | `'bb'` | Prefix written into block comments on save. |
|
|
75
|
+
| `settings` | `object` | `{}` | Forwarded to Gutenberg's `attachEditor()`. |
|
|
76
|
+
| `media` | `object` | — | `{ mode, apiUrl, csrfToken }` — see [Media](#media). |
|
|
77
|
+
| `branding` | `boolean` | `true` | Rebrand "WordPress" strings in the UI. |
|
|
78
|
+
| `contextMenu` | `boolean` | `true` | Restore right-click block menu. |
|
|
79
|
+
| `onChange` | `(html) => void` | — | Called when content changes (polled every 300 ms). |
|
|
80
|
+
|
|
81
|
+
**Returns** `Promise<EditorHandle>`:
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
editor.getContent() // current block HTML (prefixed)
|
|
85
|
+
editor.onChange(fn) // subscribe; returns unsubscribe fn
|
|
86
|
+
editor.destroy() // detach editor + stop listeners
|
|
87
|
+
editor.textarea // underlying textarea element
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### `registerBlock(name, settings)`
|
|
91
|
+
|
|
92
|
+
```js
|
|
93
|
+
import { registerBlock } from '@bladeberg/editor';
|
|
94
|
+
|
|
95
|
+
registerBlock('my-plugin/callout', { /* block settings */ });
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
> **Note:** The current isolated-block-editor bundle (v2.30) does not expose `window.wp.blocks`, so custom React blocks are queued but not registered yet. Use server-rendered blocks with [BladeBerg's PHP package](https://github.com/BladeBerg/bladeberg) instead.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Content format
|
|
103
|
+
|
|
104
|
+
Gutenberg saves blocks as HTML comments:
|
|
105
|
+
|
|
106
|
+
```html
|
|
107
|
+
<!-- bb:paragraph --><p>Hello world</p><!-- /bb:paragraph -->
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The `bb:` prefix (configurable via `blockPrefix`) keeps your database free of WordPress branding. On load, BladeBerg converts it back to `wp:` internally so Gutenberg can parse it, then converts it back on save.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Media (optional)
|
|
115
|
+
|
|
116
|
+
Wire the editor to your own upload API:
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
const editor = await createEditor({
|
|
120
|
+
target: '#editor',
|
|
121
|
+
media: {
|
|
122
|
+
mode: 'upload', // 'disabled' | 'select' | 'upload'
|
|
123
|
+
apiUrl: '/api/media', // your JSON media endpoints
|
|
124
|
+
csrfToken: getCsrfToken(), // optional
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
If you're using [BladeBerg for Laravel](https://github.com/BladeBerg/bladeberg), the backend ships ready-made routes at `/bladeberg/media`.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## SSR / Next.js / Nuxt
|
|
134
|
+
|
|
135
|
+
The editor is **browser-only**. Import it from a client component:
|
|
136
|
+
|
|
137
|
+
```jsx
|
|
138
|
+
'use client';
|
|
139
|
+
|
|
140
|
+
import { useEffect, useRef } from 'react';
|
|
141
|
+
|
|
142
|
+
export default function PostEditor({ content }) {
|
|
143
|
+
const ref = useRef(null);
|
|
144
|
+
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
let editor;
|
|
147
|
+
import('@bladeberg/editor').then(({ createEditor }) => {
|
|
148
|
+
createEditor({ target: ref.current, value: content }).then((e) => { editor = e; });
|
|
149
|
+
});
|
|
150
|
+
return () => editor?.destroy();
|
|
151
|
+
}, [content]);
|
|
152
|
+
|
|
153
|
+
return <div ref={ref} />;
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Don't forget `import '@bladeberg/editor/style.css'` somewhere in your client bundle.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Rendering stored content
|
|
162
|
+
|
|
163
|
+
This npm package is **editor-only**. To turn block HTML into visitor-facing HTML you need a renderer:
|
|
164
|
+
|
|
165
|
+
- **[BladeBerg Laravel package](https://github.com/BladeBerg/bladeberg)** — `<x-bladeberg-render>`, `Bladeberg::render()`, or `POST /bladeberg/render`
|
|
166
|
+
- **Your own backend** — parse `<!-- bb:… -->` comments and render block HTML yourself
|
|
167
|
+
- **Return raw block HTML** to the frontend and render client-side
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## How it works
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
Your React app
|
|
175
|
+
│
|
|
176
|
+
├─ import { createEditor } from '@bladeberg/editor'
|
|
177
|
+
├─ import '@bladeberg/editor/style.css'
|
|
178
|
+
│
|
|
179
|
+
▼
|
|
180
|
+
createEditor() lazy-loads isolated-block-editor.js (bundled in the package)
|
|
181
|
+
│
|
|
182
|
+
▼
|
|
183
|
+
window.wp.attachEditor(textarea) ← full Gutenberg UI
|
|
184
|
+
│
|
|
185
|
+
▼
|
|
186
|
+
editor.getContent() → "<!-- bb:paragraph -->…" → POST to your API
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
No `@wordpress/block-editor`, no `@wordpress/data`, no dependency resolver nightmares. The hard part is already done.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Development (maintainers)
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
cd packages/bladeberg
|
|
197
|
+
npm install
|
|
198
|
+
npm run build:npm # → dist-npm/bladeberg.js + style.css + isolated-block-editor.js
|
|
199
|
+
npm pack # smoke-test the tarball locally
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Publish happens via GitHub Actions on `v*` tags. See [RELEASE.md](RELEASE.md).
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## License
|
|
207
|
+
|
|
208
|
+
GPL-2.0-or-later — same as Gutenberg. See [LICENSE](LICENSE).
|