@crashbytes/contentful-richtext-editor 1.0.7 → 1.0.9

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 CHANGED
@@ -1,304 +1,533 @@
1
- # @crashbytes/contentful-richtext-editor
1
+ # Contentful Rich Text Editor
2
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.
3
+ A React component that provides a rich text editor compatible with Contentful's Rich Text field type, with automatic configuration based on Contentful field settings.
4
4
 
5
5
  ## Features
6
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
7
+ - 🔄 **Automatic Configuration**: Reads Contentful field validation settings to automatically enable/disable editor features
8
+ - 📝 **Rich Text Support**: Full support for headings, lists, tables, quotes, and text formatting
9
+ - 🔗 **Hyperlinks**: Configurable link support with URL validation
10
+ - 📎 **Embeds**: Support for embedded entries, assets, and inline entries
11
+ - 🎨 **Themes**: Multiple built-in themes (contentful, minimal, default)
12
+ - **Accessibility**: Built with accessibility in mind
13
+ - 🔧 **Customizable**: Extensive configuration options and styling hooks
14
+ - 📱 **Responsive**: Works well on mobile and desktop
15
+ - ⌨️ **Keyboard Shortcuts**: Built-in shortcuts for common actions
16
+ - 🔍 **TypeScript**: Full TypeScript support with comprehensive type definitions
13
17
 
14
- ## Supported Features
18
+ ## Installation
15
19
 
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
20
+ ```bash
21
+ npm install @your-org/contentful-rich-text-editor
22
+ # or
23
+ yarn add @your-org/contentful-rich-text-editor
24
+ ```
24
25
 
25
- ## Installation
26
+ ## Dependencies
27
+
28
+ This component requires the following peer dependencies:
26
29
 
27
30
  ```bash
28
- npm install @crashbytes/contentful-richtext-editor
31
+ npm install react @tiptap/react @tiptap/starter-kit @contentful/rich-text-types
29
32
  ```
30
33
 
31
- ## Basic Usage
34
+ ## Quick Start
32
35
 
33
- ```jsx
36
+ ### Basic Usage
37
+
38
+ ```tsx
34
39
  import React, { useState } from 'react';
35
- import { ContentfulRichTextEditor } from '@crashbytes/contentful-richtext-editor';
36
- import '@crashbytes/contentful-richtext-editor/dist/index.css';
40
+ import { ContentfulRichTextEditor } from '@your-org/contentful-rich-text-editor';
37
41
  import { Document } from '@contentful/rich-text-types';
38
42
 
39
- function App() {
40
- const [content, setContent] = useState();
41
-
42
- const handleChange = (document) => {
43
- setContent(document);
44
- console.log('Contentful document:', document);
45
- };
43
+ function MyEditor() {
44
+ const [content, setContent] = useState<Document>();
46
45
 
47
46
  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>
47
+ <ContentfulRichTextEditor
48
+ initialValue={content}
49
+ onChange={setContent}
50
+ placeholder="Start writing..."
51
+ />
56
52
  );
57
53
  }
58
-
59
- export default App;
60
54
  ```
61
55
 
62
- ## Advanced Usage
63
-
64
- ### With Contentful Entry/Asset Embedding
56
+ ### With Contentful Configuration
65
57
 
66
- ```jsx
67
- import { ContentfulRichTextEditor } from '@crashbytes/contentful-richtext-editor';
68
- import '@crashbytes/contentful-richtext-editor/dist/index.css';
58
+ ```tsx
59
+ import React, { useEffect, useState } from 'react';
60
+ import {
61
+ ContentfulRichTextEditor,
62
+ fetchContentfulFieldConfig,
63
+ ContentfulFieldConfiguration
64
+ } from '@your-org/contentful-rich-text-editor';
69
65
 
70
66
  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
- };
67
+ const [fieldConfig, setFieldConfig] = useState<ContentfulFieldConfiguration>();
68
+
69
+ useEffect(() => {
70
+ // Fetch configuration from Contentful Management API
71
+ fetchContentfulFieldConfig(
72
+ 'your-space-id',
73
+ 'your-content-type-id',
74
+ 'your-field-id',
75
+ 'your-management-token'
76
+ ).then(setFieldConfig);
77
+ }, []);
82
78
 
83
79
  return (
84
80
  <ContentfulRichTextEditor
85
- placeholder="Write your travel tip..."
86
- onChange={(doc) => saveToContentful(doc)}
81
+ fieldConfiguration={fieldConfig}
82
+ onChange={(doc) => console.log('Content changed:', doc)}
87
83
  onEmbedEntry={handleEmbedEntry}
88
84
  onEmbedAsset={handleEmbedAsset}
89
- theme="contentful"
85
+ placeholder="Start writing..."
90
86
  />
91
87
  );
92
88
  }
93
89
  ```
94
90
 
95
- ### Customizing Features
96
-
97
- ```jsx
98
- <ContentfulRichTextEditor
99
- placeholder="Simple editor..."
100
- disabledFeatures={['table', 'embed', 'quote']}
101
- theme="minimal"
102
- readonly={false}
103
- onChange={handleChange}
104
- />
105
- ```
106
-
107
- ### Controlling Available Headings and Formatting
108
-
109
- ```jsx
110
- <ContentfulRichTextEditor
111
- placeholder="Limited editor..."
112
- availableHeadings={[1, 2, 3]} // Only H1, H2, H3
113
- availableMarks={['bold', 'italic']} // Only bold and italic, no underline
114
- onChange={handleChange}
115
- />
116
- ```
117
-
118
- ### With Initial Content
119
-
120
- ```jsx
121
- import { createEmptyDocument } from '@crashbytes/contentful-richtext-editor';
122
-
123
- const initialContent = {
124
- nodeType: 'document',
125
- data: {},
126
- content: [
127
- {
128
- nodeType: 'paragraph',
129
- data: {},
130
- content: [
131
- {
132
- nodeType: 'text',
133
- value: 'Hello world!',
134
- marks: [{ type: 'bold' }],
135
- data: {}
136
- }
137
- ]
138
- }
139
- ]
140
- };
141
-
142
- <ContentfulRichTextEditor
143
- initialValue={initialContent}
144
- onChange={handleChange}
145
- />
146
- ```
147
-
148
91
  ## API Reference
149
92
 
150
- ### Props
93
+ ### ContentfulRichTextEditor Props
151
94
 
152
95
  | Prop | Type | Default | Description |
153
96
  |------|------|---------|-------------|
154
97
  | `initialValue` | `Document` | `undefined` | Initial Contentful rich text document |
155
98
  | `onChange` | `(document: Document) => void` | `undefined` | Callback when content changes |
156
- | `onEmbedEntry` | `() => Promise<any> \| void` | `undefined` | Callback for embedding Contentful entries |
157
- | `onEmbedAsset` | `() => Promise<any> \| void` | `undefined` | Callback for embedding Contentful assets |
158
- | `placeholder` | `string` | `'Start writing...'` | Placeholder text |
99
+ | `onEmbedEntry` | `() => Promise<any>` | `undefined` | Callback for embedding entries |
100
+ | `onEmbedAsset` | `() => Promise<any>` | `undefined` | Callback for embedding assets |
101
+ | `onEmbedInlineEntry` | `() => Promise<any>` | `undefined` | Callback for embedding inline entries |
102
+ | `fieldConfiguration` | `ContentfulFieldConfiguration` | `undefined` | Contentful field validation config |
159
103
  | `readonly` | `boolean` | `false` | Whether editor is read-only |
104
+ | `placeholder` | `string` | `'Start writing...'` | Placeholder text |
105
+ | `theme` | `'contentful' \| 'minimal' \| 'default'` | `'contentful'` | Editor theme |
160
106
  | `className` | `string` | `''` | Additional CSS classes |
161
- | `theme` | `'default' \| 'minimal' \| 'contentful'` | `'contentful'` | Visual theme |
162
- | `disabledFeatures` | `Array<string>` | `[]` | Features to disable |
163
- | `availableHeadings` | `Array<1\|2\|3\|4\|5\|6>` | `[1,2,3,4,5,6]` | Which heading levels to show |
164
- | `availableMarks` | `Array<'bold'\|'italic'\|'underline'>` | `['bold','italic','underline']` | Which text formatting options to show |
107
+ | `availableHeadings` | `Array<1\|2\|3\|4\|5\|6>` | `[1,2,3,4,5,6]` | Available heading levels (fallback) |
108
+ | `availableMarks` | `Array<'bold'\|'italic'\|'underline'>` | `['bold','italic','underline']` | Available text marks (fallback) |
109
+ | `disabledFeatures` | `Array<string>` | `[]` | Manually disabled features (fallback) |
165
110
 
166
- ### Disabled Features
111
+ ### Configuration Types
167
112
 
168
- You can disable specific features by passing them in the `disabledFeatures` array:
113
+ ```tsx
114
+ interface ContentfulFieldConfiguration {
115
+ validations?: Array<{
116
+ enabledMarks?: string[];
117
+ enabledNodeTypes?: string[];
118
+ }>;
119
+ settings?: {
120
+ helpText?: string;
121
+ };
122
+ }
123
+ ```
169
124
 
170
- - `'bold'` - Bold text formatting
171
- - `'italic'` - Italic text formatting
172
- - `'underline'` - Underline text formatting
173
- - `'link'` - Hyperlinks
174
- - `'lists'` - Ordered and unordered lists
175
- - `'headings'` - All heading levels
176
- - `'quote'` - Blockquotes
177
- - `'table'` - Tables
178
- - `'embed'` - Embedded content
125
+ ### Supported Node Types
179
126
 
180
- ### Utility Functions
127
+ - `paragraph` - Regular paragraphs
128
+ - `heading-1` through `heading-6` - Headings
129
+ - `unordered-list`, `ordered-list` - Lists
130
+ - `blockquote` - Quotes
131
+ - `table` - Tables
132
+ - `hyperlink` - Links
133
+ - `embedded-entry-block` - Block-level entry embeds
134
+ - `embedded-asset-block` - Block-level asset embeds
135
+ - `embedded-entry-inline` - Inline entry embeds
136
+ - `hr` - Horizontal rules
181
137
 
182
- ```jsx
183
- import {
184
- contentfulToTiptap,
185
- tiptapToContentful,
186
- validateContentfulDocument,
187
- createEmptyDocument
188
- } from '@crashbytes/contentful-richtext-editor';
138
+ ### Supported Marks
189
139
 
190
- // Convert between formats
191
- const tiptapJson = contentfulToTiptap(contentfulDocument);
192
- const contentfulDoc = tiptapToContentful(tiptapJson);
140
+ - `bold` - Bold text
141
+ - `italic` - Italic text
142
+ - `underline` - Underlined text
143
+ - `code` - Inline code
193
144
 
194
- // Validation
195
- const isValid = validateContentfulDocument(someDocument);
145
+ ## Configuration Examples
196
146
 
197
- // Create empty document
198
- const emptyDoc = createEmptyDocument();
199
- ```
147
+ ### Mock Configuration for Testing
200
148
 
201
- ## Styling
149
+ ```tsx
150
+ import { createMockFieldConfig } from '@your-org/contentful-rich-text-editor';
151
+
152
+ const mockConfig = createMockFieldConfig({
153
+ enabledMarks: ['bold', 'italic'],
154
+ enabledNodeTypes: [
155
+ 'paragraph',
156
+ 'heading-1',
157
+ 'heading-2',
158
+ 'unordered-list',
159
+ 'hyperlink',
160
+ 'embedded-entry-block'
161
+ ]
162
+ });
163
+
164
+ <ContentfulRichTextEditor fieldConfiguration={mockConfig} />
165
+ ```
202
166
 
203
- The editor comes with default styles that match Contentful's design. Import the CSS:
167
+ ### Manual Configuration (Legacy)
204
168
 
205
- ```jsx
206
- import '@crashbytes/contentful-richtext-editor/dist/index.css';
169
+ ```tsx
170
+ <ContentfulRichTextEditor
171
+ availableHeadings={[1, 2, 3]}
172
+ availableMarks={['bold', 'italic']}
173
+ disabledFeatures={['table', 'embed']}
174
+ />
207
175
  ```
208
176
 
209
- ### Custom Styling
177
+ ## Styling
210
178
 
211
- You can override the default styles by targeting the CSS classes:
179
+ The editor comes with built-in CSS classes that you can override:
212
180
 
213
181
  ```css
182
+ /* Main editor container */
214
183
  .contentful-editor {
215
- border: 2px solid #your-color;
184
+ border: 1px solid #d3dce6;
185
+ border-radius: 6px;
216
186
  }
217
187
 
188
+ /* Toolbar */
218
189
  .contentful-toolbar {
219
- background: #your-background;
190
+ background: #f7f9fa;
191
+ border-bottom: 1px solid #d3dce6;
220
192
  }
221
193
 
194
+ /* Content area */
222
195
  .contentful-editor-content {
223
- font-family: 'Your Font', sans-serif;
196
+ padding: 16px;
197
+ min-height: 200px;
198
+ }
199
+
200
+ /* Embedded content */
201
+ .contentful-embedded-entry {
202
+ background: #f0f8ff;
203
+ border: 1px dashed #2e75d4;
204
+ padding: 8px;
205
+ border-radius: 4px;
206
+ }
207
+
208
+ /* Inline embedded content */
209
+ .contentful-inline-embedded-entry {
210
+ background: #e8f4fd;
211
+ padding: 2px 4px;
212
+ border-radius: 3px;
213
+ font-weight: 600;
214
+ }
215
+
216
+ /* Tables */
217
+ .contentful-table {
218
+ border-collapse: collapse;
219
+ width: 100%;
220
+ margin: 1em 0;
221
+ }
222
+
223
+ .contentful-table-header {
224
+ background: #f7f9fa;
225
+ font-weight: 600;
226
+ }
227
+
228
+ /* Lists */
229
+ .contentful-bullet-list,
230
+ .contentful-ordered-list {
231
+ margin: 1em 0;
232
+ padding-left: 1.5em;
233
+ }
234
+
235
+ /* Quotes */
236
+ .contentful-blockquote {
237
+ border-left: 4px solid #2e75d4;
238
+ margin: 1em 0;
239
+ padding-left: 1em;
240
+ font-style: italic;
224
241
  }
225
242
  ```
226
243
 
227
- ## Themes
244
+ ## Advanced Usage
228
245
 
229
- ### Contentful Theme (Default)
230
- Matches Contentful's native editor appearance.
246
+ ### Custom Embed Handlers
231
247
 
232
- ### Minimal Theme
233
- Clean, minimal design with reduced visual elements.
248
+ ```tsx
249
+ const handleEmbedEntry = async () => {
250
+ // Open your entry selector modal/component
251
+ const selectedEntry = await openEntrySelector();
252
+ return {
253
+ sys: { id: selectedEntry.id, type: 'Entry' },
254
+ fields: { title: selectedEntry.title }
255
+ };
256
+ };
234
257
 
235
- ### Default Theme
236
- Standard rich text editor appearance with serif fonts.
258
+ const handleEmbedAsset = async () => {
259
+ const selectedAsset = await openAssetSelector();
260
+ return {
261
+ sys: { id: selectedAsset.id, type: 'Asset' },
262
+ fields: {
263
+ title: selectedAsset.title,
264
+ file: { url: selectedAsset.url }
265
+ }
266
+ };
267
+ };
268
+
269
+ const handleEmbedInlineEntry = async () => {
270
+ const selectedEntry = await openInlineEntrySelector();
271
+ return {
272
+ sys: { id: selectedEntry.id, type: 'Entry' },
273
+ fields: { name: selectedEntry.name }
274
+ };
275
+ };
276
+ ```
237
277
 
238
- ## Integration with Next.js
278
+ ### Keyboard Shortcuts
239
279
 
240
- ```jsx
241
- // pages/editor.tsx or app/editor/page.tsx
242
- import dynamic from 'next/dynamic';
280
+ - `Ctrl/Cmd + B` - Bold
281
+ - `Ctrl/Cmd + I` - Italic
282
+ - `Ctrl/Cmd + U` - Underline
283
+ - `Ctrl/Cmd + K` - Add link
284
+ - `Ctrl/Cmd + Shift + E` - Embed entry
285
+ - `Ctrl/Cmd + Shift + A` - Embed asset
286
+ - `Ctrl/Cmd + Shift + I` - Embed inline entry
287
+ - `Ctrl/Cmd + Z` - Undo
288
+ - `Ctrl/Cmd + Y` / `Ctrl/Cmd + Shift + Z` - Redo
243
289
 
244
- const ContentfulEditor = dynamic(
245
- () => import('@crashbytes/contentful-richtext-editor').then(mod => mod.ContentfulRichTextEditor),
246
- { ssr: false }
290
+ ### Content Validation and Analysis
291
+
292
+ ```tsx
293
+ import {
294
+ validateContentfulDocument,
295
+ extractPlainText,
296
+ countWords,
297
+ findEmbeddedContent
298
+ } from '@your-org/contentful-rich-text-editor';
299
+
300
+ const handleChange = (document: Document) => {
301
+ // Validate document structure
302
+ if (validateContentfulDocument(document)) {
303
+ console.log('Document is valid');
304
+ }
305
+
306
+ // Extract plain text
307
+ const plainText = extractPlainText(document);
308
+ console.log('Plain text:', plainText);
309
+
310
+ // Count words
311
+ const wordCount = countWords(document);
312
+ console.log('Word count:', wordCount);
313
+
314
+ // Find embedded content
315
+ const embedded = findEmbeddedContent(document);
316
+ console.log('Embedded content:', embedded);
317
+
318
+ saveDocument(document);
319
+ };
320
+ ```
321
+
322
+ ### Content Sanitization
323
+
324
+ ```tsx
325
+ import { sanitizeContentfulDocument } from '@your-org/contentful-rich-text-editor';
326
+
327
+ // Sanitize content based on allowed features
328
+ const sanitizedDocument = sanitizeContentfulDocument(
329
+ document,
330
+ ['paragraph', 'heading-1', 'heading-2', 'unordered-list'], // allowed nodes
331
+ ['bold', 'italic'] // allowed marks
247
332
  );
333
+ ```
248
334
 
249
- export default function EditorPage() {
250
- return (
251
- <div>
252
- <ContentfulEditor
253
- placeholder="Write something amazing..."
254
- onChange={(doc) => console.log(doc)}
255
- />
256
- </div>
257
- );
258
- }
335
+ ## Environment Variables
336
+
337
+ For API integration, set these environment variables:
338
+
339
+ ```env
340
+ REACT_APP_CONTENTFUL_SPACE_ID=your_space_id
341
+ REACT_APP_CONTENTFUL_CONTENT_TYPE_ID=your_content_type_id
342
+ REACT_APP_CONTENTFUL_FIELD_ID=your_rich_text_field_id
343
+ REACT_APP_CONTENTFUL_MANAGEMENT_TOKEN=your_management_token
344
+ ```
345
+
346
+ ## Utilities
347
+
348
+ ### Configuration Parser
349
+
350
+ ```tsx
351
+ import { parseContentfulFieldConfig } from '@your-org/contentful-rich-text-editor';
352
+
353
+ const config = parseContentfulFieldConfig(fieldConfiguration);
354
+ // Returns parsed configuration with boolean flags for each feature
355
+ console.log(config.allowHyperlinks); // true/false
356
+ console.log(config.availableHeadings); // [1, 2, 3]
357
+ console.log(config.disabledFeatures); // ['table', 'embed']
358
+ ```
359
+
360
+ ### Content Transformation
361
+
362
+ ```tsx
363
+ import {
364
+ contentfulToTiptap,
365
+ tiptapToContentful
366
+ } from '@your-org/contentful-rich-text-editor';
367
+
368
+ // Convert between formats
369
+ const tiptapContent = contentfulToTiptap(contentfulDocument);
370
+ const contentfulContent = tiptapToContentful(tiptapDocument);
259
371
  ```
260
372
 
261
373
  ## TypeScript Support
262
374
 
263
- This package is written in TypeScript and includes full type definitions. All Contentful rich text types are re-exported for convenience:
375
+ This package is written in TypeScript and includes full type definitions. All major types are exported:
264
376
 
265
377
  ```tsx
266
- import type {
267
- Document,
268
- Block,
269
- Inline,
270
- Text,
271
- ContentfulRichTextEditorProps
272
- } from '@crashbytes/contentful-richtext-editor';
378
+ import type {
379
+ ContentfulRichTextEditorProps,
380
+ ContentfulFieldConfiguration,
381
+ ParsedEditorConfig,
382
+ EmbeddedEntry,
383
+ EmbeddedAsset,
384
+ ContentfulDocument,
385
+ TiptapDocument
386
+ } from '@your-org/contentful-rich-text-editor';
273
387
  ```
274
388
 
275
389
  ## Browser Support
276
390
 
277
- - Chrome 80+
278
- - Firefox 78+
279
- - Safari 13+
280
- - Edge 80+
391
+ - Chrome 60+
392
+ - Firefox 55+
393
+ - Safari 12+
394
+ - Edge 79+
281
395
 
282
- ## Contributing
396
+ ## Performance Considerations
397
+
398
+ - The editor uses React.memo internally for performance optimization
399
+ - Large documents (>1000 nodes) may experience slower rendering
400
+ - Consider implementing virtualization for very large content
401
+ - Use the `readonly` prop when displaying content to improve performance
402
+
403
+ ## Accessibility
404
+
405
+ The editor is built with accessibility in mind:
283
406
 
284
- Contributions are welcome! Please feel free to submit a Pull Request.
407
+ - Full keyboard navigation support
408
+ - Screen reader compatible
409
+ - ARIA labels and descriptions
410
+ - High contrast mode support
411
+ - Focus management
412
+
413
+ ## Troubleshooting
414
+
415
+ ### Common Issues
416
+
417
+ 1. **Editor not loading**: Check that all peer dependencies are installed
418
+ 2. **Configuration not applying**: Ensure `fieldConfiguration` prop is properly set
419
+ 3. **Embed callbacks not working**: Verify that embed handlers return proper Contentful objects
420
+ 4. **Styling issues**: Check that CSS is properly imported and not conflicting
421
+
422
+ ### Debug Mode
423
+
424
+ Enable debug logging:
425
+
426
+ ```tsx
427
+ // Add to your component
428
+ useEffect(() => {
429
+ if (process.env.NODE_ENV === 'development') {
430
+ window.contentfulEditorDebug = true;
431
+ }
432
+ }, []);
433
+ ```
434
+
435
+ ## Contributing
285
436
 
286
437
  1. Fork the repository
287
438
  2. Create your feature branch (`git checkout -b feature/amazing-feature`)
288
- 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
439
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
289
440
  4. Push to the branch (`git push origin feature/amazing-feature`)
290
441
  5. Open a Pull Request
291
442
 
292
- ## License
443
+ ### Development Setup
444
+
445
+ ```bash
446
+ # Clone the repo
447
+ git clone https://github.com/your-org/contentful-rich-text-editor.git
448
+
449
+ # Install dependencies
450
+ npm install
293
451
 
294
- MIT © [CrashBytes](https://github.com/CrashBytes)
452
+ # Start development server
453
+ npm run dev
295
454
 
296
- ## Related Packages
455
+ # Run tests
456
+ npm test
297
457
 
298
- - [@contentful/rich-text-react-renderer](https://www.npmjs.com/package/@contentful/rich-text-react-renderer) - For rendering Contentful rich text
299
- - [@contentful/rich-text-types](https://www.npmjs.com/package/@contentful/rich-text-types) - Contentful rich text type definitions
300
- - [@tiptap/react](https://www.npmjs.com/package/@tiptap/react) - The underlying editor framework
458
+ # Build for production
459
+ npm run build
460
+ ```
301
461
 
302
- ---
462
+ ## License
303
463
 
304
- **Made with ❤️ for the Contentful community**
464
+ MIT License
465
+
466
+ Copyright (c) 2024 [Your Name]
467
+
468
+ Permission is hereby granted, free of charge, to any person obtaining a copy
469
+ of this software and associated documentation files (the "Software"), to deal
470
+ in the Software without restriction, including without limitation the rights
471
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
472
+ copies of the Software, and to permit persons to whom the Software is
473
+ furnished to do so, subject to the following conditions:
474
+
475
+ The above copyright notice and this permission notice shall be included in all
476
+ copies or substantial portions of the Software.
477
+
478
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
479
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
480
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
481
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
482
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
483
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
484
+ SOFTWARE.
485
+
486
+ ## Changelog
487
+
488
+ ### v2.0.0 - 2024-01-XX
489
+ - ✨ **BREAKING**: Added automatic configuration from Contentful field settings
490
+ - ✨ Added support for inline embedded entries
491
+ - ✨ Added comprehensive utility functions (sanitization, analysis, validation)
492
+ - ✨ Added keyboard shortcuts for embed actions
493
+ - ✨ Enhanced TypeScript support with better type definitions
494
+ - ✨ Added content analysis utilities (word count, plain text extraction)
495
+ - 🔧 Improved accessibility with better ARIA support
496
+ - 🔧 Better error handling and validation
497
+ - 🔧 Performance optimizations
498
+ - 🐛 Fixed link handling in complex nested structures
499
+ - 🐛 Fixed table rendering issues
500
+ - 🐛 Various bug fixes and improvements
501
+
502
+ ### v1.2.0 - 2023-12-XX
503
+ - ✨ Added table support
504
+ - ✨ Added themes (minimal, default, contentful)
505
+ - 🔧 Improved toolbar layout and responsiveness
506
+ - 🐛 Fixed undo/redo functionality
507
+
508
+ ### v1.1.0 - 2023-11-XX
509
+ - ✨ Added embedded assets support
510
+ - ✨ Added link functionality
511
+ - 🔧 Improved content transformation
512
+ - 🐛 Fixed list nesting issues
513
+
514
+ ### v1.0.0 - 2023-10-XX
515
+ - 🎉 Initial release
516
+ - ✨ Basic rich text editing
517
+ - ✨ Contentful document format support
518
+ - ✨ Embedded entries support
519
+ - ✨ Manual configuration options
520
+
521
+ ## Support
522
+
523
+ For support, please:
524
+
525
+ 1. Check the [documentation](https://github.com/your-org/contentful-rich-text-editor/docs)
526
+ 2. Search [existing issues](https://github.com/your-org/contentful-rich-text-editor/issues)
527
+ 3. Create a [new issue](https://github.com/your-org/contentful-rich-text-editor/issues/new) with detailed information
528
+
529
+ ## Related Projects
530
+
531
+ - [@contentful/rich-text-renderer](https://github.com/contentful/rich-text) - Official Contentful rich text renderer
532
+ - [@tiptap/react](https://tiptap.dev/) - The underlying editor framework
533
+ - [Contentful Management API](https://www.contentful.com/developers/docs/references/content-management-api/) - For fetching field configurations