@brevitaz/brv-text-editor 1.0.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/README.md +348 -0
- package/dist/brv-text-editor.css +395 -0
- package/dist/brv-text-editor.es.js +21716 -0
- package/dist/brv-text-editor.es.js.map +1 -0
- package/dist/brv-text-editor.umd.js +21717 -0
- package/dist/brv-text-editor.umd.js.map +1 -0
- package/package.json +81 -0
package/README.md
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
# brv-text-editor
|
|
2
|
+
|
|
3
|
+
A fully-functional React rich text editor and preview component inspired by Basecamp 3.
|
|
4
|
+
Built on [Tiptap](https://tiptap.dev/) (ProseMirror) + [Lucide React](https://lucide.dev/) icons.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
| Feature | Details |
|
|
11
|
+
|---|---|
|
|
12
|
+
| **Formatting** | Bold, italic, underline, strikethrough, inline code |
|
|
13
|
+
| **Headings** | H1, H2, H3 via dropdown |
|
|
14
|
+
| **Lists** | Bullet, numbered, task (checkbox) lists |
|
|
15
|
+
| **Blocks** | Blockquote, fenced code block, horizontal rule |
|
|
16
|
+
| **Alignment** | Left, center, right text alignment |
|
|
17
|
+
| **Media** | Insert links (with edit/remove popover) and images by URL |
|
|
18
|
+
| **History** | Undo / Redo (⌘Z / ⌘⇧Z) |
|
|
19
|
+
| **Word count** | Live character and word count in the footer |
|
|
20
|
+
| **Preview** | `RichTextPreview` renders saved HTML in a Basecamp-style card with tabbed source view and emoji reactions |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install brv-text-editor
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
> **Peer dependencies** – React 18+ must already be installed in your project.
|
|
31
|
+
> `react` and `react-dom` are **not** bundled inside the package.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# If you don't have React yet:
|
|
35
|
+
npm install react react-dom
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
### 1. Import the CSS (once, in your app entry)
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
// main.jsx / main.tsx / _app.jsx
|
|
46
|
+
import 'brv-text-editor/dist/brv-text-editor.css'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 2. Use the editor
|
|
50
|
+
|
|
51
|
+
```jsx
|
|
52
|
+
import { RichTextEditor } from 'brv-text-editor'
|
|
53
|
+
|
|
54
|
+
function MyPage() {
|
|
55
|
+
const handleSave = (html) => {
|
|
56
|
+
console.log('Saved HTML:', html)
|
|
57
|
+
// send to your API, store in state, etc.
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<RichTextEditor
|
|
62
|
+
placeholder="Write something…"
|
|
63
|
+
onSubmit={handleSave}
|
|
64
|
+
submitLabel="Post note"
|
|
65
|
+
showActions={true}
|
|
66
|
+
/>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 3. Show a preview after saving
|
|
72
|
+
|
|
73
|
+
```jsx
|
|
74
|
+
import { useState } from 'react'
|
|
75
|
+
import { RichTextEditor, RichTextPreview } from 'brv-text-editor'
|
|
76
|
+
|
|
77
|
+
const AUTHOR = { name: 'Jane Doe', initials: 'JD', avatarColor: '#1a6b3c' }
|
|
78
|
+
|
|
79
|
+
function NotesPage() {
|
|
80
|
+
const [notes, setNotes] = useState([])
|
|
81
|
+
|
|
82
|
+
const handleSave = (html) => {
|
|
83
|
+
setNotes(prev => [
|
|
84
|
+
{ id: Date.now(), html, timestamp: new Date().toLocaleString() },
|
|
85
|
+
...prev,
|
|
86
|
+
])
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<>
|
|
91
|
+
<RichTextEditor onSubmit={handleSave} submitLabel="Post" showActions />
|
|
92
|
+
|
|
93
|
+
{notes.map(note => (
|
|
94
|
+
<RichTextPreview
|
|
95
|
+
key={note.id}
|
|
96
|
+
html={note.html}
|
|
97
|
+
author={AUTHOR}
|
|
98
|
+
timestamp={note.timestamp}
|
|
99
|
+
onDismiss={() => setNotes(n => n.filter(x => x.id !== note.id))}
|
|
100
|
+
/>
|
|
101
|
+
))}
|
|
102
|
+
</>
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## API
|
|
110
|
+
|
|
111
|
+
### `<RichTextEditor />`
|
|
112
|
+
|
|
113
|
+
| Prop | Type | Default | Description |
|
|
114
|
+
|---|---|---|---|
|
|
115
|
+
| `initialContent` | `string` | `''` | Initial HTML content loaded into the editor |
|
|
116
|
+
| `placeholder` | `string` | `'Write something…'` | Placeholder shown when editor is empty |
|
|
117
|
+
| `onChange` | `(html: string) => void` | — | Called on every change with the current HTML |
|
|
118
|
+
| `onSubmit` | `(html: string) => void` | — | Called when the submit button is clicked |
|
|
119
|
+
| `onCancel` | `() => void` | — | Called when the cancel button is clicked |
|
|
120
|
+
| `submitLabel` | `string` | `'Save'` | Label for the submit button |
|
|
121
|
+
| `showActions` | `boolean` | `true` | Whether to show the footer Save/Cancel bar |
|
|
122
|
+
| `minHeight` | `number` | `140` | Minimum editor height in pixels |
|
|
123
|
+
| `autofocus` | `boolean` | `false` | Whether to focus the editor on mount |
|
|
124
|
+
|
|
125
|
+
### `<RichTextPreview />`
|
|
126
|
+
|
|
127
|
+
| Prop | Type | Default | Description |
|
|
128
|
+
|---|---|---|---|
|
|
129
|
+
| `html` | `string` | `''` | Raw HTML string to render |
|
|
130
|
+
| `author` | `{ name, initials, avatarColor? }` | `{ name:'Anonymous', initials:'A' }` | Author info shown in the card header |
|
|
131
|
+
| `timestamp` | `string` | `''` | Human-readable timestamp string |
|
|
132
|
+
| `onDismiss` | `() => void` | — | If provided, shows a × button to remove the card |
|
|
133
|
+
| `showReactions` | `boolean` | `true` | Whether to show the emoji reactions row |
|
|
134
|
+
| `reactions` | `string[]` | `['👍','❤️','🎉','🙌']` | Emoji list for the reactions row |
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Publishing for your company
|
|
139
|
+
|
|
140
|
+
You have two options: a **private npm registry** (recommended) or a **direct Git dependency**.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### Option A — Private npm registry (recommended)
|
|
145
|
+
|
|
146
|
+
This is the cleanest approach. Developers run a single `npm install` and get the package like any other.
|
|
147
|
+
|
|
148
|
+
#### Step 1 — Set up a registry
|
|
149
|
+
|
|
150
|
+
Choose one:
|
|
151
|
+
|
|
152
|
+
| Option | Notes |
|
|
153
|
+
|---|---|
|
|
154
|
+
| **GitHub Packages** | Free for private repos; scoped package (`@your-org/brv-text-editor`). Good if you already use GitHub. |
|
|
155
|
+
| **npm private registry** | Paid; works with unscoped names. |
|
|
156
|
+
| **Verdaccio** (self-hosted) | Free, runs on your own server/container. Full npm protocol compatible. |
|
|
157
|
+
| **AWS CodeArtifact / JFrog** | Enterprise options; cost depends on usage. |
|
|
158
|
+
|
|
159
|
+
#### Step 2 — Scope the package (recommended for private registries)
|
|
160
|
+
|
|
161
|
+
In `package.json`, rename to a scoped name:
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"name": "@your-org/brv-text-editor"
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
This prevents name collisions with the public registry.
|
|
170
|
+
|
|
171
|
+
#### Step 3 — Authenticate and publish
|
|
172
|
+
|
|
173
|
+
**GitHub Packages example:**
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# 1. Create a Personal Access Token (PAT) with write:packages scope on GitHub
|
|
177
|
+
|
|
178
|
+
# 2. Login to the GitHub registry
|
|
179
|
+
npm login --registry=https://npm.pkg.github.com --scope=@your-org
|
|
180
|
+
|
|
181
|
+
# 3. Build the library
|
|
182
|
+
npm run build:lib
|
|
183
|
+
|
|
184
|
+
# 4. Publish
|
|
185
|
+
npm publish --registry=https://npm.pkg.github.com
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Verdaccio example:**
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# 1. Start Verdaccio (or point to your hosted instance)
|
|
192
|
+
npx verdaccio # → http://localhost:4873
|
|
193
|
+
|
|
194
|
+
# 2. Create an account (first time only)
|
|
195
|
+
npm adduser --registry http://localhost:4873
|
|
196
|
+
|
|
197
|
+
# 3. Build and publish
|
|
198
|
+
npm run build:lib
|
|
199
|
+
npm publish --registry http://localhost:4873
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### Step 4 — Configure developers' machines
|
|
203
|
+
|
|
204
|
+
Developers need to tell npm where to find your scoped packages.
|
|
205
|
+
Create or update `.npmrc` in their project (or the monorepo root):
|
|
206
|
+
|
|
207
|
+
```ini
|
|
208
|
+
# .npmrc – checked into source control
|
|
209
|
+
@your-org:registry=https://npm.pkg.github.com
|
|
210
|
+
# or for Verdaccio:
|
|
211
|
+
# @your-org:registry=http://your-verdaccio-host:4873
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
They also need to authenticate once:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
npm login --registry=https://npm.pkg.github.com --scope=@your-org
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
For CI/CD, use an automation token stored as a secret:
|
|
221
|
+
|
|
222
|
+
```ini
|
|
223
|
+
# .npmrc in CI environment
|
|
224
|
+
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
|
|
225
|
+
@your-org:registry=https://npm.pkg.github.com
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
#### Step 5 — Developers install and use it
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
npm install @your-org/brv-text-editor
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
```jsx
|
|
235
|
+
import '@your-org/brv-text-editor/dist/brv-text-editor.css'
|
|
236
|
+
import { RichTextEditor, RichTextPreview } from '@your-org/brv-text-editor'
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
#### Step 6 — Publishing updates
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
# Bump the version (choose: patch | minor | major)
|
|
243
|
+
npm version patch
|
|
244
|
+
|
|
245
|
+
# Rebuild and publish
|
|
246
|
+
npm run build:lib && npm publish --registry <your-registry-url>
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Use semantic versioning:
|
|
250
|
+
- `patch` (1.0.1) — bug fixes
|
|
251
|
+
- `minor` (1.1.0) — new features, backwards-compatible
|
|
252
|
+
- `major` (2.0.0) — breaking changes
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
### Option B — Git dependency (no registry needed)
|
|
257
|
+
|
|
258
|
+
If you just want to share quickly within your organization without setting up a registry, push the repo to your internal Git host and developers install directly from Git:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
npm install git+https://github.com/your-org/brv-text-editor.git
|
|
262
|
+
# or SSH:
|
|
263
|
+
npm install git+ssh://git@github.com/your-org/brv-text-editor.git
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Important:** The `dist/` folder must be committed to the repo for this to work, because npm won't run `build:lib` automatically on install.
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
# Before pushing for the first time (and after each release):
|
|
270
|
+
npm run build:lib
|
|
271
|
+
git add dist/
|
|
272
|
+
git commit -m "chore: rebuild dist for v1.0.x"
|
|
273
|
+
git push
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
To pin to a specific version, use a tag:
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Tag a release
|
|
280
|
+
git tag v1.0.1
|
|
281
|
+
git push origin v1.0.1
|
|
282
|
+
|
|
283
|
+
# Install that exact tag
|
|
284
|
+
npm install git+https://github.com/your-org/brv-text-editor.git#v1.0.1
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Local development / testing the library
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
# In this repo — build the library and create a local link
|
|
293
|
+
npm run build:lib
|
|
294
|
+
npm link
|
|
295
|
+
|
|
296
|
+
# In your consumer app's folder
|
|
297
|
+
npm link brv-text-editor # or @your-org/brv-text-editor
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Or use `npm pack` to simulate exactly what gets published:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
npm pack
|
|
304
|
+
# → brv-text-editor-1.0.0.tgz
|
|
305
|
+
|
|
306
|
+
# In your consumer app:
|
|
307
|
+
npm install /path/to/brv-text-editor-1.0.0.tgz
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Project structure
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
rich-text-editor/
|
|
316
|
+
├── dist/ ← Library output (git-ignored for private registry flow)
|
|
317
|
+
│ ├── brv-text-editor.es.js ← ES module bundle
|
|
318
|
+
│ ├── brv-text-editor.umd.js ← UMD/CJS bundle
|
|
319
|
+
│ └── brv-text-editor.css ← Extracted stylesheet
|
|
320
|
+
├── src/
|
|
321
|
+
│ ├── index.js ← Library entry (exports both components)
|
|
322
|
+
│ ├── index.css ← All styles (ProseMirror + preview)
|
|
323
|
+
│ ├── components/
|
|
324
|
+
│ │ ├── RichTextEditor.jsx ← Editor component
|
|
325
|
+
│ │ └── RichTextPreview.jsx ← Preview card component
|
|
326
|
+
│ ├── App.jsx ← Demo application
|
|
327
|
+
│ └── main.jsx ← Demo entry point
|
|
328
|
+
├── vite.config.js ← Demo app Vite config
|
|
329
|
+
├── vite.lib.config.js ← Library build Vite config
|
|
330
|
+
└── package.json
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Scripts
|
|
336
|
+
|
|
337
|
+
| Command | Description |
|
|
338
|
+
|---|---|
|
|
339
|
+
| `npm run dev` | Start the demo app dev server |
|
|
340
|
+
| `npm run build` | Build the demo app |
|
|
341
|
+
| `npm run build:lib` | Build the distributable library → `dist/` |
|
|
342
|
+
| `npm run preview` | Preview the built demo app |
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## License
|
|
347
|
+
|
|
348
|
+
MIT
|