@crashbytes/contentful-richtext-editor 1.0.9 → 1.0.11

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,533 +1,179 @@
1
- # Contentful Rich Text Editor
1
+ # Release v2.0.0 - Major Feature Update 🎉
2
2
 
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.
3
+ ## 🚀 What's New
4
4
 
5
- ## Features
5
+ This major release introduces **automatic configuration** from Contentful field settings, significantly enhancing the developer experience and ensuring your editor UI always matches your Contentful configuration.
6
6
 
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
7
+ ### Major New Features
17
8
 
18
- ## Installation
9
+ - **🔄 Automatic Contentful Configuration**: The editor now reads your Contentful field validation settings and automatically enables/disables toolbar features
10
+ - **📝 Inline Entry Support**: Added support for inline embedded entries (as configured in Contentful)
11
+ - **⌨️ Keyboard Shortcuts**: Built-in shortcuts for common actions (`Cmd/Ctrl + Shift + E` for entries, `Cmd/Ctrl + Shift + A` for assets, etc.)
12
+ - **🔍 Enhanced TypeScript Support**: Comprehensive type definitions and better developer experience
13
+ - **📊 Content Analysis Utilities**: New utilities for word counting, plain text extraction, and content validation
19
14
 
20
- ```bash
21
- npm install @your-org/contentful-rich-text-editor
22
- # or
23
- yarn add @your-org/contentful-rich-text-editor
24
- ```
25
-
26
- ## Dependencies
27
-
28
- This component requires the following peer dependencies:
29
-
30
- ```bash
31
- npm install react @tiptap/react @tiptap/starter-kit @contentful/rich-text-types
32
- ```
33
-
34
- ## Quick Start
35
-
36
- ### Basic Usage
37
-
38
- ```tsx
39
- import React, { useState } from 'react';
40
- import { ContentfulRichTextEditor } from '@your-org/contentful-rich-text-editor';
41
- import { Document } from '@contentful/rich-text-types';
42
-
43
- function MyEditor() {
44
- const [content, setContent] = useState<Document>();
45
-
46
- return (
47
- <ContentfulRichTextEditor
48
- initialValue={content}
49
- onChange={setContent}
50
- placeholder="Start writing..."
51
- />
52
- );
53
- }
54
- ```
55
-
56
- ### With Contentful Configuration
57
-
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';
65
-
66
- function ContentfulEditor() {
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
- }, []);
78
-
79
- return (
80
- <ContentfulRichTextEditor
81
- fieldConfiguration={fieldConfig}
82
- onChange={(doc) => console.log('Content changed:', doc)}
83
- onEmbedEntry={handleEmbedEntry}
84
- onEmbedAsset={handleEmbedAsset}
85
- placeholder="Start writing..."
86
- />
87
- );
88
- }
89
- ```
90
-
91
- ## API Reference
92
-
93
- ### ContentfulRichTextEditor Props
94
-
95
- | Prop | Type | Default | Description |
96
- |------|------|---------|-------------|
97
- | `initialValue` | `Document` | `undefined` | Initial Contentful rich text document |
98
- | `onChange` | `(document: Document) => void` | `undefined` | Callback when content changes |
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 |
103
- | `readonly` | `boolean` | `false` | Whether editor is read-only |
104
- | `placeholder` | `string` | `'Start writing...'` | Placeholder text |
105
- | `theme` | `'contentful' \| 'minimal' \| 'default'` | `'contentful'` | Editor theme |
106
- | `className` | `string` | `''` | Additional CSS classes |
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) |
110
-
111
- ### Configuration Types
15
+ ### 🔧 Enhanced Features
112
16
 
113
- ```tsx
114
- interface ContentfulFieldConfiguration {
115
- validations?: Array<{
116
- enabledMarks?: string[];
117
- enabledNodeTypes?: string[];
118
- }>;
119
- settings?: {
120
- helpText?: string;
121
- };
122
- }
123
- ```
124
-
125
- ### Supported Node Types
126
-
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
137
-
138
- ### Supported Marks
17
+ - **Smart Toolbar**: Toolbar buttons now appear/disappear based on your Contentful field configuration
18
+ - **Better Error Handling**: Improved error messages and validation
19
+ - **Performance Optimizations**: Faster rendering and better memory usage
20
+ - **Accessibility Improvements**: Enhanced ARIA support and keyboard navigation
139
21
 
140
- - `bold` - Bold text
141
- - `italic` - Italic text
142
- - `underline` - Underlined text
143
- - `code` - Inline code
22
+ ### 🎨 Developer Experience
144
23
 
145
- ## Configuration Examples
24
+ - **Configuration Parser**: New utility to parse Contentful field settings
25
+ - **Mock Configuration**: Easy testing with `createMockFieldConfig()`
26
+ - **Backward Compatibility**: Existing manual configuration still works
27
+ - **Comprehensive Documentation**: Updated with examples and API reference
146
28
 
147
- ### Mock Configuration for Testing
148
-
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
- });
29
+ ## 🛠️ Installation
163
30
 
164
- <ContentfulRichTextEditor fieldConfiguration={mockConfig} />
31
+ ```bash
32
+ npm install @crashbytes/contentful-richtext-editor@2.0.0
165
33
  ```
166
34
 
167
- ### Manual Configuration (Legacy)
35
+ ## 🔄 Migration from v1.x
168
36
 
37
+ ### Automatic Configuration (Recommended)
169
38
  ```tsx
39
+ // Before (v1.x)
170
40
  <ContentfulRichTextEditor
171
41
  availableHeadings={[1, 2, 3]}
172
42
  availableMarks={['bold', 'italic']}
173
- disabledFeatures={['table', 'embed']}
43
+ disabledFeatures={['table']}
174
44
  />
175
- ```
176
-
177
- ## Styling
178
-
179
- The editor comes with built-in CSS classes that you can override:
180
-
181
- ```css
182
- /* Main editor container */
183
- .contentful-editor {
184
- border: 1px solid #d3dce6;
185
- border-radius: 6px;
186
- }
187
45
 
188
- /* Toolbar */
189
- .contentful-toolbar {
190
- background: #f7f9fa;
191
- border-bottom: 1px solid #d3dce6;
192
- }
193
-
194
- /* Content area */
195
- .contentful-editor-content {
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;
241
- }
242
- ```
243
-
244
- ## Advanced Usage
245
-
246
- ### Custom Embed Handlers
247
-
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
- };
257
-
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
- };
46
+ // After (v2.x) - Automatically configured!
47
+ <ContentfulRichTextEditor
48
+ fieldConfiguration={contentfulFieldConfig}
49
+ onEmbedInlineEntry={handleInlineEntry} // New!
50
+ />
276
51
  ```
277
52
 
278
- ### Keyboard Shortcuts
279
-
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
289
-
290
- ### Content Validation and Analysis
291
-
53
+ ### New Props Available
292
54
  ```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);
55
+ interface ContentfulRichTextEditorProps {
56
+ // New in v2.0
57
+ fieldConfiguration?: ContentfulFieldConfiguration;
58
+ onEmbedInlineEntry?: () => Promise<any> | void;
313
59
 
314
- // Find embedded content
315
- const embedded = findEmbeddedContent(document);
316
- console.log('Embedded content:', embedded);
317
-
318
- saveDocument(document);
319
- };
60
+ // Existing props still work (backward compatible)
61
+ availableHeadings?: Array<1 | 2 | 3 | 4 | 5 | 6>;
62
+ availableMarks?: Array<'bold' | 'italic' | 'underline'>;
63
+ disabledFeatures?: Array<string>;
64
+ }
320
65
  ```
321
66
 
322
- ### Content Sanitization
323
-
67
+ ### Fetching Configuration from Contentful
324
68
  ```tsx
325
- import { sanitizeContentfulDocument } from '@your-org/contentful-rich-text-editor';
69
+ import { fetchContentfulFieldConfig } from '@crashbytes/contentful-richtext-editor';
326
70
 
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
71
+ const fieldConfig = await fetchContentfulFieldConfig(
72
+ 'space-id',
73
+ 'content-type-id',
74
+ 'field-id',
75
+ 'management-token'
332
76
  );
333
77
  ```
334
78
 
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
79
+ ## 📋 New Utilities
349
80
 
81
+ ### Content Analysis
350
82
  ```tsx
351
- import { parseContentfulFieldConfig } from '@your-org/contentful-rich-text-editor';
83
+ import {
84
+ extractPlainText,
85
+ countWords,
86
+ findEmbeddedContent,
87
+ sanitizeContentfulDocument
88
+ } from '@crashbytes/contentful-richtext-editor';
352
89
 
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']
90
+ const plainText = extractPlainText(document);
91
+ const wordCount = countWords(document);
92
+ const embedded = findEmbeddedContent(document);
358
93
  ```
359
94
 
360
- ### Content Transformation
361
-
95
+ ### Configuration Management
362
96
  ```tsx
363
97
  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);
371
- ```
372
-
373
- ## TypeScript Support
98
+ parseContentfulFieldConfig,
99
+ createMockFieldConfig
100
+ } from '@crashbytes/contentful-richtext-editor';
374
101
 
375
- This package is written in TypeScript and includes full type definitions. All major types are exported:
102
+ // Parse Contentful config
103
+ const parsed = parseContentfulFieldConfig(fieldConfig);
376
104
 
377
- ```tsx
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';
105
+ // Create mock for testing
106
+ const mockConfig = createMockFieldConfig({
107
+ enabledMarks: ['bold', 'italic'],
108
+ enabledNodeTypes: ['paragraph', 'heading-1', 'unordered-list']
109
+ });
387
110
  ```
388
111
 
389
- ## Browser Support
112
+ ## ⌨️ New Keyboard Shortcuts
390
113
 
391
- - Chrome 60+
392
- - Firefox 55+
393
- - Safari 12+
394
- - Edge 79+
114
+ - `Cmd/Ctrl + Shift + E` - Embed entry
115
+ - `Cmd/Ctrl + Shift + A` - Embed asset
116
+ - `Cmd/Ctrl + Shift + I` - Embed inline entry
117
+ - `Cmd/Ctrl + K` - Add/edit link
118
+ - Standard formatting shortcuts (Bold, Italic, Underline)
395
119
 
396
- ## Performance Considerations
120
+ ## 🐛 Bug Fixes
397
121
 
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
122
+ - Fixed TypeScript compilation warnings
123
+ - Improved link handling in complex nested structures
124
+ - Fixed table rendering issues
125
+ - Better handling of embedded content transformation
126
+ - Resolved build process issues
402
127
 
403
- ## Accessibility
128
+ ## 🔧 Technical Improvements
404
129
 
405
- The editor is built with accessibility in mind:
130
+ - **Build System**: Improved Rollup configuration
131
+ - **Type Safety**: Better TypeScript definitions throughout
132
+ - **Performance**: Optimized re-renders and memory usage
133
+ - **Code Quality**: Enhanced error boundaries and validation
406
134
 
407
- - Full keyboard navigation support
408
- - Screen reader compatible
409
- - ARIA labels and descriptions
410
- - High contrast mode support
411
- - Focus management
135
+ ## 📚 Documentation
412
136
 
413
- ## Troubleshooting
137
+ - **Complete API Reference**: Full documentation of all props and methods
138
+ - **Usage Examples**: 5 different implementation examples
139
+ - **Migration Guide**: Step-by-step upgrade instructions
140
+ - **TypeScript Support**: Full type definitions and examples
414
141
 
415
- ### Common Issues
142
+ ## 🎯 What's Next
416
143
 
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
144
+ We're already working on v2.1 with:
145
+ - Real-time collaboration support
146
+ - Advanced table editing features
147
+ - Plugin system for custom extensions
148
+ - More keyboard shortcuts and accessibility improvements
421
149
 
422
- ### Debug Mode
150
+ ## 🤝 Contributing
423
151
 
424
- Enable debug logging:
152
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
425
153
 
426
- ```tsx
427
- // Add to your component
428
- useEffect(() => {
429
- if (process.env.NODE_ENV === 'development') {
430
- window.contentfulEditorDebug = true;
431
- }
432
- }, []);
433
- ```
154
+ ## 📖 Full Documentation
434
155
 
435
- ## Contributing
156
+ - [README](README.md) - Complete setup and usage guide
157
+ - [API Reference](docs/API.md) - Detailed prop and method documentation
158
+ - [Examples](examples/) - Implementation examples
159
+ - [Changelog](CHANGELOG.md) - Complete version history
436
160
 
437
- 1. Fork the repository
438
- 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
439
- 3. Commit your changes (`git commit -m 'Add amazing feature'`)
440
- 4. Push to the branch (`git push origin feature/amazing-feature`)
441
- 5. Open a Pull Request
161
+ ## 🔗 Links
442
162
 
443
- ### Development Setup
163
+ - **GitHub**: https://github.com/your-org/contentful-richtext-editor
164
+ - **npm**: https://www.npmjs.com/package/@crashbytes/contentful-richtext-editor
165
+ - **Issues**: https://github.com/your-org/contentful-richtext-editor/issues
166
+ - **Discussions**: https://github.com/your-org/contentful-richtext-editor/discussions
444
167
 
445
- ```bash
446
- # Clone the repo
447
- git clone https://github.com/your-org/contentful-rich-text-editor.git
168
+ ## 💝 Acknowledgments
448
169
 
449
- # Install dependencies
450
- npm install
170
+ Special thanks to:
171
+ - The Contentful team for their excellent Rich Text API
172
+ - The TipTap team for the amazing editor framework
173
+ - All early adopters and contributors who provided feedback
451
174
 
452
- # Start development server
453
- npm run dev
175
+ ---
454
176
 
455
- # Run tests
456
- npm test
457
-
458
- # Build for production
459
- npm run build
460
- ```
177
+ **Full Changelog**: https://github.com/your-org/contentful-richtext-editor/compare/v1.0.10...v2.0.0
461
178
 
462
- ## License
463
-
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
179
+ **Happy editing! 🎉**
package/dist/index.css CHANGED
@@ -1 +1 @@
1
- .contentful-editor{background:#fff;border:1px solid #d3dce6;border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif}.contentful-editor--loading{align-items:center;color:#68737d;display:flex;justify-content:center;min-height:200px}.contentful-toolbar{background:#f7f9fa;border-bottom:1px solid #d3dce6;border-radius:6px 6px 0 0;padding:8px 12px}.contentful-toolbar,.contentful-toolbar__group{align-items:center;display:flex;gap:4px}.contentful-toolbar__group--right{margin-left:auto}.contentful-toolbar__separator{background:#d3dce6;height:24px;margin:0 8px;width:1px}.contentful-toolbar__select{background:#fff;border:1px solid #d3dce6;border-radius:4px;font-size:14px;min-width:120px;padding:4px 8px}.contentful-toolbar__select:focus{border-color:#2e75d4;box-shadow:0 0 0 2px rgba(46,117,212,.2);outline:none}.contentful-toolbar__button{align-items:center;background:transparent;border:1px solid transparent;border-radius:4px;cursor:pointer;display:flex;font-size:14px;height:32px;justify-content:center;line-height:1;min-width:32px;padding:6px 8px}.contentful-toolbar__button:hover{background:#e5ebed;border-color:#d3dce6}.contentful-toolbar__button:disabled{cursor:not-allowed;opacity:.5}.contentful-toolbar__button--active{background:#2e75d4;border-color:#2e75d4;color:#fff}.contentful-toolbar__button--active:hover{background:#1e5aa8;border-color:#1e5aa8}.contentful-toolbar__link-input{align-items:center;display:flex;gap:4px;margin-left:8px}.contentful-toolbar__link-input input{border:1px solid #d3dce6;border-radius:4px;font-size:14px;padding:4px 8px;width:200px}.contentful-toolbar__link-input input:focus{border-color:#2e75d4;box-shadow:0 0 0 2px rgba(46,117,212,.2);outline:none}.contentful-toolbar__link-input button{background:#fff;border:1px solid #d3dce6;border-radius:4px;cursor:pointer;font-size:12px;padding:4px 8px}.contentful-toolbar__embed-dropdown{position:relative}.contentful-toolbar__embed-button{background:#2e75d4;border:1px solid #2e75d4;border-radius:4px;color:#fff;cursor:pointer;font-size:14px;font-weight:500;padding:6px 12px}.contentful-toolbar__embed-button:hover{background:#1e5aa8;border-color:#1e5aa8}.contentful-toolbar__embed-dropdown:hover .contentful-toolbar__embed-menu{display:block}.contentful-toolbar__embed-menu{background:#fff;border:1px solid #d3dce6;border-radius:4px;box-shadow:0 2px 8px rgba(0,0,0,.15);display:none;min-width:120px;position:absolute;right:0;top:100%;z-index:100}.contentful-toolbar__embed-option{background:none;border:none;cursor:pointer;display:block;font-size:14px;padding:8px 12px;text-align:left;width:100%}.contentful-toolbar__embed-option:hover{background:#f7f9fa}.contentful-editor__content-wrapper{position:relative}.contentful-editor__content{min-height:200px}.contentful-editor-content{color:#2c3e50;font-size:16px;line-height:1.6;outline:none;padding:16px}.contentful-editor-content:empty:before{color:#68737d;content:attr(data-placeholder);pointer-events:none}.contentful-editor-content h1{font-size:2em;font-weight:600;line-height:1.2;margin:1em 0 .5em}.contentful-editor-content h2{font-size:1.5em;font-weight:600;line-height:1.3;margin:1em 0 .5em}.contentful-editor-content h3{font-size:1.25em;font-weight:600;line-height:1.4;margin:1em 0 .5em}.contentful-editor-content h4,.contentful-editor-content h5,.contentful-editor-content h6{font-size:1em;font-weight:600;line-height:1.5;margin:1em 0 .5em}.contentful-editor-content p{margin:0 0 1em}.contentful-editor-content p:last-child{margin-bottom:0}.contentful-bullet-list,.contentful-ordered-list{margin:1em 0;padding-left:1.5em}.contentful-bullet-list li,.contentful-ordered-list li{margin:.25em 0}.contentful-blockquote{border-left:4px solid #2e75d4;color:#68737d;font-style:italic;margin:1em 0;padding-left:1em}.contentful-link{color:#2e75d4;text-decoration:underline}.contentful-link:hover{color:#1e5aa8}.contentful-table{border:1px solid #d3dce6;border-collapse:collapse;margin:1em 0;width:100%}.contentful-table-cell,.contentful-table-header{border:1px solid #d3dce6;padding:8px 12px;text-align:left}.contentful-table-header{background:#f7f9fa;font-weight:600}.contentful-editor--minimal{border:none;border-radius:0}.contentful-editor--minimal .contentful-toolbar{background:#fff;border-bottom:1px solid #e1e8ed;border-radius:0}.contentful-editor--default .contentful-editor-content{font-family:Georgia,serif}.contentful-editor:focus-within{border-color:#2e75d4;box-shadow:0 0 0 2px rgba(46,117,212,.2)}@media (max-width:768px){.contentful-toolbar{flex-wrap:wrap}.contentful-toolbar__select{min-width:100px}.contentful-editor-content{font-size:14px;padding:12px}}
1
+ .contentful-editor{background:#fff;border:1px solid #d3dce6;border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif}.contentful-editor--borderless{border:none!important}.contentful-editor--loading{align-items:center;color:#68737d;display:flex;justify-content:center;min-height:200px}.contentful-toolbar{background:#f7f9fa;border-bottom:1px solid #d3dce6;border-radius:6px 6px 0 0;padding:8px 12px}.contentful-toolbar,.contentful-toolbar__group{align-items:center;display:flex;gap:4px}.contentful-toolbar__group--right{margin-left:auto}.contentful-toolbar__separator{background:#d3dce6;height:24px;margin:0 8px;width:1px}.contentful-toolbar__select{background:#fff;border:1px solid #d3dce6;border-radius:4px;font-size:14px;min-width:120px;padding:4px 8px}.contentful-toolbar__select:focus{border-color:#2e75d4;box-shadow:0 0 0 2px rgba(46,117,212,.2);outline:none}.contentful-toolbar__button{align-items:center;background:transparent;border:1px solid transparent;border-radius:4px;cursor:pointer;display:flex;font-size:14px;height:32px;justify-content:center;line-height:1;min-width:32px;padding:6px 8px}.contentful-toolbar__button:hover{background:#e5ebed;border-color:#d3dce6}.contentful-toolbar__button:disabled{cursor:not-allowed;opacity:.5}.contentful-toolbar__button--active{background:#2e75d4;border-color:#2e75d4;color:#fff}.contentful-toolbar__button--active:hover{background:#1e5aa8;border-color:#1e5aa8}.contentful-toolbar__link-input{align-items:center;display:flex;gap:4px;margin-left:8px}.contentful-toolbar__link-input input{border:1px solid #d3dce6;border-radius:4px;font-size:14px;padding:4px 8px;width:200px}.contentful-toolbar__link-input input:focus{border-color:#2e75d4;box-shadow:0 0 0 2px rgba(46,117,212,.2);outline:none}.contentful-toolbar__link-input button{background:#fff;border:1px solid #d3dce6;border-radius:4px;cursor:pointer;font-size:12px;padding:4px 8px}.contentful-toolbar__embed-dropdown{position:relative}.contentful-toolbar__embed-button{background:#2e75d4;border:1px solid #2e75d4;border-radius:4px;color:#fff;cursor:pointer;font-size:14px;font-weight:500;padding:6px 12px}.contentful-toolbar__embed-button:hover{background:#1e5aa8;border-color:#1e5aa8}.contentful-toolbar__embed-dropdown:hover .contentful-toolbar__embed-menu{display:block}.contentful-toolbar__embed-menu{background:#fff;border:1px solid #d3dce6;border-radius:4px;box-shadow:0 2px 8px rgba(0,0,0,.15);display:none;min-width:120px;position:absolute;right:0;top:100%;z-index:100}.contentful-toolbar__embed-option{background:none;border:none;cursor:pointer;display:block;font-size:14px;padding:8px 12px;text-align:left;width:100%}.contentful-toolbar__embed-option:hover{background:#f7f9fa}.contentful-editor__content-wrapper{position:relative}.contentful-editor__content{min-height:200px}.contentful-editor-content{color:#2c3e50;font-size:16px;line-height:1.6;outline:none;padding:16px}.contentful-editor-content:empty:before{color:#68737d;content:attr(data-placeholder);pointer-events:none}.contentful-editor-content h1{font-size:2em;font-weight:600;line-height:1.2;margin:1em 0 .5em}.contentful-editor-content h2{font-size:1.5em;font-weight:600;line-height:1.3;margin:1em 0 .5em}.contentful-editor-content h3{font-size:1.25em;font-weight:600;line-height:1.4;margin:1em 0 .5em}.contentful-editor-content h4,.contentful-editor-content h5,.contentful-editor-content h6{font-size:1em;font-weight:600;line-height:1.5;margin:1em 0 .5em}.contentful-editor-content p{margin:0 0 1em}.contentful-editor-content p:last-child{margin-bottom:0}.contentful-bullet-list,.contentful-ordered-list{margin:1em 0;padding-left:1.5em}.contentful-bullet-list li,.contentful-ordered-list li{margin:.25em 0}.contentful-blockquote{border-left:4px solid #2e75d4;color:#68737d;font-style:italic;margin:1em 0;padding-left:1em}.contentful-link{color:#2e75d4;text-decoration:underline}.contentful-link:hover{color:#1e5aa8}.contentful-table{border:1px solid #d3dce6;border-collapse:collapse;margin:1em 0;width:100%}.contentful-table-cell,.contentful-table-header{border:1px solid #d3dce6;padding:8px 12px;text-align:left}.contentful-table-header{background:#f7f9fa;font-weight:600}.contentful-editor--minimal{border:none;border-radius:0}.contentful-editor--minimal .contentful-toolbar{background:#fff;border-bottom:1px solid #e1e8ed;border-radius:0}.contentful-editor--default .contentful-editor-content{font-family:Georgia,serif}.contentful-editor:focus-within{border-color:#2e75d4;box-shadow:0 0 0 2px rgba(46,117,212,.2)}@media (max-width:768px){.contentful-toolbar{flex-wrap:wrap}.contentful-toolbar__select{min-width:100px}.contentful-editor-content{font-size:14px;padding:12px}}