@crashbytes/contentful-richtext-editor 1.0.0 → 1.0.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 +291 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# @crashbytes/contentful-richtext-editor
|
|
2
|
+
|
|
3
|
+
A modern, Tiptap-based rich text editor that's fully compatible with Contentful's rich text format. Provides the same editing experience as Contentful's native editor while maintaining perfect compatibility with Contentful's document structure.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
✅ **Full Contentful Compatibility** - Seamless conversion between Contentful and Tiptap formats
|
|
8
|
+
✅ **Modern UI** - Clean, intuitive interface matching Contentful's design
|
|
9
|
+
✅ **TypeScript Support** - Complete type safety with Contentful's rich text types
|
|
10
|
+
✅ **Extensible** - Built on Tiptap v2 for easy customization
|
|
11
|
+
✅ **Lightweight** - Tree-shakeable, only import what you need
|
|
12
|
+
✅ **Responsive** - Works on desktop and mobile devices
|
|
13
|
+
|
|
14
|
+
## Supported Features
|
|
15
|
+
|
|
16
|
+
- **Text Formatting**: Bold, italic, underline
|
|
17
|
+
- **Headings**: H1 through H6
|
|
18
|
+
- **Lists**: Ordered and unordered lists
|
|
19
|
+
- **Links**: Hyperlinks with URL validation
|
|
20
|
+
- **Tables**: Full table support with headers
|
|
21
|
+
- **Quotes**: Blockquotes
|
|
22
|
+
- **Embedded Content**: Callbacks for Contentful entries and assets
|
|
23
|
+
- **Undo/Redo**: Full history support
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @crashbytes/contentful-richtext-editor
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Basic Usage
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import React, { useState } from 'react';
|
|
35
|
+
import { ContentfulRichTextEditor } from '@crashbytes/contentful-richtext-editor';
|
|
36
|
+
import '@crashbytes/contentful-richtext-editor/dist/index.css';
|
|
37
|
+
import { Document } from '@contentful/rich-text-types';
|
|
38
|
+
|
|
39
|
+
function App() {
|
|
40
|
+
const [content, setContent] = useState<Document>();
|
|
41
|
+
|
|
42
|
+
const handleChange = (document: Document) => {
|
|
43
|
+
setContent(document);
|
|
44
|
+
console.log('Contentful document:', document);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div>
|
|
49
|
+
<h1>My Rich Text Editor</h1>
|
|
50
|
+
<ContentfulRichTextEditor
|
|
51
|
+
placeholder="Start writing your content..."
|
|
52
|
+
onChange={handleChange}
|
|
53
|
+
initialValue={content}
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default App;
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Advanced Usage
|
|
63
|
+
|
|
64
|
+
### With Contentful Entry/Asset Embedding
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { ContentfulRichTextEditor } from '@crashbytes/contentful-richtext-editor';
|
|
68
|
+
import '@crashbytes/contentful-richtext-editor/dist/index.css';
|
|
69
|
+
|
|
70
|
+
function ContentfulEditor() {
|
|
71
|
+
const handleEmbedEntry = async () => {
|
|
72
|
+
// Your logic to select a Contentful entry
|
|
73
|
+
const entry = await openEntrySelector();
|
|
74
|
+
return entry;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const handleEmbedAsset = async () => {
|
|
78
|
+
// Your logic to select a Contentful asset
|
|
79
|
+
const asset = await openAssetSelector();
|
|
80
|
+
return asset;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<ContentfulRichTextEditor
|
|
85
|
+
placeholder="Write your travel tip..."
|
|
86
|
+
onChange={(doc) => saveToContentful(doc)}
|
|
87
|
+
onEmbedEntry={handleEmbedEntry}
|
|
88
|
+
onEmbedAsset={handleEmbedAsset}
|
|
89
|
+
theme="contentful"
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Customizing Features
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
<ContentfulRichTextEditor
|
|
99
|
+
placeholder="Simple editor..."
|
|
100
|
+
disabledFeatures={['table', 'embed', 'quote']}
|
|
101
|
+
theme="minimal"
|
|
102
|
+
readonly={false}
|
|
103
|
+
onChange={handleChange}
|
|
104
|
+
/>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### With Initial Content
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
import { createEmptyDocument } from '@crashbytes/contentful-richtext-editor';
|
|
111
|
+
|
|
112
|
+
const initialContent = {
|
|
113
|
+
nodeType: 'document',
|
|
114
|
+
data: {},
|
|
115
|
+
content: [
|
|
116
|
+
{
|
|
117
|
+
nodeType: 'paragraph',
|
|
118
|
+
data: {},
|
|
119
|
+
content: [
|
|
120
|
+
{
|
|
121
|
+
nodeType: 'text',
|
|
122
|
+
value: 'Hello world!',
|
|
123
|
+
marks: [{ type: 'bold' }],
|
|
124
|
+
data: {}
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
<ContentfulRichTextEditor
|
|
132
|
+
initialValue={initialContent}
|
|
133
|
+
onChange={handleChange}
|
|
134
|
+
/>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## API Reference
|
|
138
|
+
|
|
139
|
+
### Props
|
|
140
|
+
|
|
141
|
+
| Prop | Type | Default | Description |
|
|
142
|
+
|------|------|---------|-------------|
|
|
143
|
+
| `initialValue` | `Document` | `undefined` | Initial Contentful rich text document |
|
|
144
|
+
| `onChange` | `(document: Document) => void` | `undefined` | Callback when content changes |
|
|
145
|
+
| `onEmbedEntry` | `() => Promise<any> \| void` | `undefined` | Callback for embedding Contentful entries |
|
|
146
|
+
| `onEmbedAsset` | `() => Promise<any> \| void` | `undefined` | Callback for embedding Contentful assets |
|
|
147
|
+
| `placeholder` | `string` | `'Start writing...'` | Placeholder text |
|
|
148
|
+
| `readonly` | `boolean` | `false` | Whether editor is read-only |
|
|
149
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
150
|
+
| `theme` | `'default' \| 'minimal' \| 'contentful'` | `'contentful'` | Visual theme |
|
|
151
|
+
| `disabledFeatures` | `Array<string>` | `[]` | Features to disable |
|
|
152
|
+
|
|
153
|
+
### Disabled Features
|
|
154
|
+
|
|
155
|
+
You can disable specific features by passing them in the `disabledFeatures` array:
|
|
156
|
+
|
|
157
|
+
- `'bold'` - Bold text formatting
|
|
158
|
+
- `'italic'` - Italic text formatting
|
|
159
|
+
- `'underline'` - Underline text formatting
|
|
160
|
+
- `'link'` - Hyperlinks
|
|
161
|
+
- `'lists'` - Ordered and unordered lists
|
|
162
|
+
- `'headings'` - All heading levels
|
|
163
|
+
- `'quote'` - Blockquotes
|
|
164
|
+
- `'table'` - Tables
|
|
165
|
+
- `'embed'` - Embedded content
|
|
166
|
+
|
|
167
|
+
### Utility Functions
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
import {
|
|
171
|
+
contentfulToTiptap,
|
|
172
|
+
tiptapToContentful,
|
|
173
|
+
validateContentfulDocument,
|
|
174
|
+
createEmptyDocument
|
|
175
|
+
} from '@crashbytes/contentful-richtext-editor';
|
|
176
|
+
|
|
177
|
+
// Convert between formats
|
|
178
|
+
const tiptapJson = contentfulToTiptap(contentfulDocument);
|
|
179
|
+
const contentfulDoc = tiptapToContentful(tiptapJson);
|
|
180
|
+
|
|
181
|
+
// Validation
|
|
182
|
+
const isValid = validateContentfulDocument(someDocument);
|
|
183
|
+
|
|
184
|
+
// Create empty document
|
|
185
|
+
const emptyDoc = createEmptyDocument();
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Styling
|
|
189
|
+
|
|
190
|
+
The editor comes with default styles that match Contentful's design. Import the CSS:
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import '@crashbytes/contentful-richtext-editor/dist/index.css';
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Custom Styling
|
|
197
|
+
|
|
198
|
+
You can override the default styles by targeting the CSS classes:
|
|
199
|
+
|
|
200
|
+
```css
|
|
201
|
+
.contentful-editor {
|
|
202
|
+
border: 2px solid #your-color;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.contentful-toolbar {
|
|
206
|
+
background: #your-background;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.contentful-editor-content {
|
|
210
|
+
font-family: 'Your Font', sans-serif;
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Themes
|
|
215
|
+
|
|
216
|
+
### Contentful Theme (Default)
|
|
217
|
+
Matches Contentful's native editor appearance.
|
|
218
|
+
|
|
219
|
+
### Minimal Theme
|
|
220
|
+
Clean, minimal design with reduced visual elements.
|
|
221
|
+
|
|
222
|
+
### Default Theme
|
|
223
|
+
Standard rich text editor appearance with serif fonts.
|
|
224
|
+
|
|
225
|
+
## Integration with Next.js
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
// pages/editor.tsx or app/editor/page.tsx
|
|
229
|
+
import dynamic from 'next/dynamic';
|
|
230
|
+
|
|
231
|
+
const ContentfulEditor = dynamic(
|
|
232
|
+
() => import('@crashbytes/contentful-richtext-editor').then(mod => mod.ContentfulRichTextEditor),
|
|
233
|
+
{ ssr: false }
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
export default function EditorPage() {
|
|
237
|
+
return (
|
|
238
|
+
<div>
|
|
239
|
+
<ContentfulEditor
|
|
240
|
+
placeholder="Write something amazing..."
|
|
241
|
+
onChange={(doc) => console.log(doc)}
|
|
242
|
+
/>
|
|
243
|
+
</div>
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## TypeScript Support
|
|
249
|
+
|
|
250
|
+
This package is written in TypeScript and includes full type definitions. All Contentful rich text types are re-exported for convenience:
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
import type {
|
|
254
|
+
Document,
|
|
255
|
+
Block,
|
|
256
|
+
Inline,
|
|
257
|
+
Text,
|
|
258
|
+
ContentfulRichTextEditorProps
|
|
259
|
+
} from '@crashbytes/contentful-richtext-editor';
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Browser Support
|
|
263
|
+
|
|
264
|
+
- Chrome 80+
|
|
265
|
+
- Firefox 78+
|
|
266
|
+
- Safari 13+
|
|
267
|
+
- Edge 80+
|
|
268
|
+
|
|
269
|
+
## Contributing
|
|
270
|
+
|
|
271
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
272
|
+
|
|
273
|
+
1. Fork the repository
|
|
274
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
275
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
276
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
277
|
+
5. Open a Pull Request
|
|
278
|
+
|
|
279
|
+
## License
|
|
280
|
+
|
|
281
|
+
MIT © [CrashBytes](https://github.com/CrashBytes)
|
|
282
|
+
|
|
283
|
+
## Related Packages
|
|
284
|
+
|
|
285
|
+
- [@contentful/rich-text-react-renderer](https://www.npmjs.com/package/@contentful/rich-text-react-renderer) - For rendering Contentful rich text
|
|
286
|
+
- [@contentful/rich-text-types](https://www.npmjs.com/package/@contentful/rich-text-types) - Contentful rich text type definitions
|
|
287
|
+
- [@tiptap/react](https://www.npmjs.com/package/@tiptap/react) - The underlying editor framework
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
**Made with ❤️ for the Contentful community**
|
package/package.json
CHANGED