@crashbytes/contentful-richtext-editor 1.0.3 → 1.0.5

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
@@ -24,105 +24,126 @@ A modern, Tiptap-based rich text editor that's fully compatible with Contentful'
24
24
 
25
25
  ## Installation
26
26
 
27
- npm install @crashbytes/contentful-richtext-editor
27
+ ```
28
+ npm install @crashbytes/contentful-richtext-editor
29
+ ```
28
30
 
29
31
  ## Basic Usage
30
32
 
31
- import React, { useState } from 'react';
32
- import { ContentfulRichTextEditor } from '@crashbytes/contentful-richtext-editor';
33
- import '@crashbytes/contentful-richtext-editor/dist/index.css';
34
- import { Document } from '@contentful/rich-text-types';
35
-
36
- function App() {
37
- const [content, setContent] = useState<Document>();
38
-
39
- const handleChange = (document: Document) => {
40
- setContent(document);
41
- console.log('Contentful document:', document);
42
- };
43
-
44
- return (
45
- <div>
46
- <h1>My Rich Text Editor</h1>
47
- <ContentfulRichTextEditor
48
- placeholder="Start writing your content..."
49
- onChange={handleChange}
50
- initialValue={content}
51
- />
52
- </div>
53
- );
54
- }
55
-
56
- export default App;
33
+ ```javascript
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();
41
+
42
+ const handleChange = (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
+ ```
57
61
 
58
62
  ## Advanced Usage
59
63
 
60
64
  ### With Contentful Entry/Asset Embedding
61
65
 
62
- import { ContentfulRichTextEditor } from '@crashbytes/contentful-richtext-editor';
63
- import '@crashbytes/contentful-richtext-editor/dist/index.css';
64
-
65
- function ContentfulEditor() {
66
- const handleEmbedEntry = async () => {
67
- // Your logic to select a Contentful entry
68
- const entry = await openEntrySelector();
69
- return entry;
70
- };
71
-
72
- const handleEmbedAsset = async () => {
73
- // Your logic to select a Contentful asset
74
- const asset = await openAssetSelector();
75
- return asset;
76
- };
77
-
78
- return (
79
- <ContentfulRichTextEditor
80
- placeholder="Write your travel tip..."
81
- onChange={(doc) => saveToContentful(doc)}
82
- onEmbedEntry={handleEmbedEntry}
83
- onEmbedAsset={handleEmbedAsset}
84
- theme="contentful"
85
- />
86
- );
87
- }
66
+ ```javascript
67
+ import { ContentfulRichTextEditor } from '@crashbytes/contentful-richtext-editor';
68
+ import '@crashbytes/contentful-richtext-editor/dist/index.css';
88
69
 
89
- ### Customizing Features
70
+ function ContentfulEditor() {
71
+ const handleEmbedEntry = async () => {
72
+ // Your logic to select a Contentful entry
73
+ const entry = await openEntrySelector();
74
+ return entry;
75
+ };
90
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 (
91
84
  <ContentfulRichTextEditor
92
- placeholder="Simple editor..."
93
- disabledFeatures={['table', 'embed', 'quote']}
94
- theme="minimal"
95
- readonly={false}
96
- onChange={handleChange}
85
+ placeholder="Write your travel tip..."
86
+ onChange={(doc) => saveToContentful(doc)}
87
+ onEmbedEntry={handleEmbedEntry}
88
+ onEmbedAsset={handleEmbedAsset}
89
+ theme="contentful"
97
90
  />
91
+ );
92
+ }
93
+ ```
94
+
95
+ ### Customizing Features
96
+
97
+ ```javascript
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
+ ```javascript
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
+ ```
98
117
 
99
118
  ### With Initial Content
100
119
 
101
- import { createEmptyDocument } from '@crashbytes/contentful-richtext-editor';
120
+ ```javascript
121
+ import { createEmptyDocument } from '@crashbytes/contentful-richtext-editor';
102
122
 
103
- const initialContent = {
104
- nodeType: 'document',
123
+ const initialContent = {
124
+ nodeType: 'document',
125
+ data: {},
126
+ content: [
127
+ {
128
+ nodeType: 'paragraph',
105
129
  data: {},
106
130
  content: [
107
131
  {
108
- nodeType: 'paragraph',
109
- data: {},
110
- content: [
111
- {
112
- nodeType: 'text',
113
- value: 'Hello world!',
114
- marks: [{ type: 'bold' }],
115
- data: {}
116
- }
117
- ]
132
+ nodeType: 'text',
133
+ value: 'Hello world!',
134
+ marks: [{ type: 'bold' }],
135
+ data: {}
118
136
  }
119
137
  ]
120
- };
138
+ }
139
+ ]
140
+ };
121
141
 
122
- <ContentfulRichTextEditor
123
- initialValue={initialContent}
124
- onChange={handleChange}
125
- />
142
+ <ContentfulRichTextEditor
143
+ initialValue={initialContent}
144
+ onChange={handleChange}
145
+ />
146
+ ```
126
147
 
127
148
  ## API Reference
128
149
 
@@ -139,6 +160,8 @@ A modern, Tiptap-based rich text editor that's fully compatible with Contentful'
139
160
  | `className` | `string` | `''` | Additional CSS classes |
140
161
  | `theme` | `'default' \| 'minimal' \| 'contentful'` | `'contentful'` | Visual theme |
141
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 |
142
165
 
143
166
  ### Disabled Features
144
167
 
@@ -156,44 +179,50 @@ You can disable specific features by passing them in the `disabledFeatures` arra
156
179
 
157
180
  ### Utility Functions
158
181
 
159
- import {
160
- contentfulToTiptap,
161
- tiptapToContentful,
162
- validateContentfulDocument,
163
- createEmptyDocument
164
- } from '@crashbytes/contentful-richtext-editor';
182
+ ```javascript
183
+ import {
184
+ contentfulToTiptap,
185
+ tiptapToContentful,
186
+ validateContentfulDocument,
187
+ createEmptyDocument
188
+ } from '@crashbytes/contentful-richtext-editor';
165
189
 
166
- // Convert between formats
167
- const tiptapJson = contentfulToTiptap(contentfulDocument);
168
- const contentfulDoc = tiptapToContentful(tiptapJson);
190
+ // Convert between formats
191
+ const tiptapJson = contentfulToTiptap(contentfulDocument);
192
+ const contentfulDoc = tiptapToContentful(tiptapJson);
169
193
 
170
- // Validation
171
- const isValid = validateContentfulDocument(someDocument);
194
+ // Validation
195
+ const isValid = validateContentfulDocument(someDocument);
172
196
 
173
- // Create empty document
174
- const emptyDoc = createEmptyDocument();
197
+ // Create empty document
198
+ const emptyDoc = createEmptyDocument();
199
+ ```
175
200
 
176
201
  ## Styling
177
202
 
178
203
  The editor comes with default styles that match Contentful's design. Import the CSS:
179
204
 
180
- import '@crashbytes/contentful-richtext-editor/dist/index.css';
205
+ ```javascript
206
+ import '@crashbytes/contentful-richtext-editor/dist/index.css';
207
+ ```
181
208
 
182
209
  ### Custom Styling
183
210
 
184
211
  You can override the default styles by targeting the CSS classes:
185
212
 
186
- .contentful-editor {
187
- border: 2px solid #your-color;
188
- }
213
+ ```css
214
+ .contentful-editor {
215
+ border: 2px solid #your-color;
216
+ }
189
217
 
190
- .contentful-toolbar {
191
- background: #your-background;
192
- }
218
+ .contentful-toolbar {
219
+ background: #your-background;
220
+ }
193
221
 
194
- .contentful-editor-content {
195
- font-family: 'Your Font', sans-serif;
196
- }
222
+ .contentful-editor-content {
223
+ font-family: 'Your Font', sans-serif;
224
+ }
225
+ ```
197
226
 
198
227
  ## Themes
199
228
 
@@ -208,36 +237,40 @@ Standard rich text editor appearance with serif fonts.
208
237
 
209
238
  ## Integration with Next.js
210
239
 
211
- // pages/editor.tsx or app/editor/page.tsx
212
- import dynamic from 'next/dynamic';
213
-
214
- const ContentfulEditor = dynamic(
215
- () => import('@crashbytes/contentful-richtext-editor').then(mod => mod.ContentfulRichTextEditor),
216
- { ssr: false }
217
- );
218
-
219
- export default function EditorPage() {
220
- return (
221
- <div>
222
- <ContentfulEditor
223
- placeholder="Write something amazing..."
224
- onChange={(doc) => console.log(doc)}
225
- />
226
- </div>
227
- );
228
- }
240
+ ```javascript
241
+ // pages/editor.tsx or app/editor/page.tsx
242
+ import dynamic from 'next/dynamic';
243
+
244
+ const ContentfulEditor = dynamic(
245
+ () => import('@crashbytes/contentful-richtext-editor').then(mod => mod.ContentfulRichTextEditor),
246
+ { ssr: false }
247
+ );
248
+
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
+ }
259
+ ```
229
260
 
230
261
  ## TypeScript Support
231
262
 
232
263
  This package is written in TypeScript and includes full type definitions. All Contentful rich text types are re-exported for convenience:
233
264
 
234
- import type {
235
- Document,
236
- Block,
237
- Inline,
238
- Text,
239
- ContentfulRichTextEditorProps
240
- } from '@crashbytes/contentful-richtext-editor';
265
+ ```javascript
266
+ import type {
267
+ Document,
268
+ Block,
269
+ Inline,
270
+ Text,
271
+ ContentfulRichTextEditorProps
272
+ } from '@crashbytes/contentful-richtext-editor';
273
+ ```
241
274
 
242
275
  ## Browser Support
243
276
 
@@ -20,6 +20,10 @@ export interface ContentfulRichTextEditorProps {
20
20
  disabledFeatures?: Array<'bold' | 'italic' | 'underline' | 'link' | 'lists' | 'headings' | 'quote' | 'table' | 'embed'>;
21
21
  /** Custom styling options */
22
22
  theme?: 'default' | 'minimal' | 'contentful';
23
+ /** Which heading levels to make available (1-6) */
24
+ availableHeadings?: Array<1 | 2 | 3 | 4 | 5 | 6>;
25
+ /** Which text formatting marks to make available */
26
+ availableMarks?: Array<'bold' | 'italic' | 'underline'>;
23
27
  }
24
28
  export declare const ContentfulRichTextEditor: React.FC<ContentfulRichTextEditorProps>;
25
29
  export default ContentfulRichTextEditor;
@@ -5,6 +5,8 @@ interface ToolbarProps {
5
5
  onEmbedEntry?: () => void;
6
6
  onEmbedAsset?: () => void;
7
7
  disabledFeatures?: Array<string>;
8
+ availableHeadings?: Array<1 | 2 | 3 | 4 | 5 | 6>;
9
+ availableMarks?: Array<'bold' | 'italic' | 'underline'>;
8
10
  }
9
11
  export declare const ContentfulToolbar: React.FC<ToolbarProps>;
10
12
  export {};
package/dist/index.esm.js CHANGED
@@ -26529,10 +26529,11 @@ const Underline = Mark.create({
26529
26529
  },
26530
26530
  });
26531
26531
 
26532
- const ContentfulToolbar = ({ editor, onEmbedEntry, onEmbedAsset, disabledFeatures = [] }) => {
26532
+ const ContentfulToolbar = ({ editor, onEmbedEntry, onEmbedAsset, disabledFeatures = [], availableHeadings = [1, 2, 3, 4, 5, 6], availableMarks = ['bold', 'italic', 'underline'] }) => {
26533
26533
  const [showLinkInput, setShowLinkInput] = useState(false);
26534
26534
  const [linkUrl, setLinkUrl] = useState('');
26535
26535
  const isDisabled = (feature) => disabledFeatures.includes(feature);
26536
+ const isMarkAvailable = (mark) => availableMarks.includes(mark);
26536
26537
  const handleHeadingChange = (level) => {
26537
26538
  if (level === 0) {
26538
26539
  editor.chain().focus().setParagraph().run();
@@ -26561,14 +26562,15 @@ const ContentfulToolbar = ({ editor, onEmbedEntry, onEmbedAsset, disabledFeature
26561
26562
  editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
26562
26563
  };
26563
26564
  const getActiveHeading = () => {
26564
- for (let i = 1; i <= 6; i++) {
26565
- if (editor.isActive('heading', { level: i })) {
26566
- return `Heading ${i}`;
26565
+ for (const level of availableHeadings) {
26566
+ if (editor.isActive('heading', { level })) {
26567
+ return `Heading ${level}`;
26567
26568
  }
26568
26569
  }
26569
26570
  return 'Normal text';
26570
26571
  };
26571
- return (jsxs("div", { className: "contentful-toolbar", children: [jsxs("div", { className: "contentful-toolbar__group", children: [!isDisabled('headings') && (jsxs("select", { className: "contentful-toolbar__select", value: getActiveHeading(), onChange: (e) => {
26572
+ const hasHeadings = !isDisabled('headings') && availableHeadings.length > 0;
26573
+ return (jsxs("div", { className: "contentful-toolbar", children: [jsxs("div", { className: "contentful-toolbar__group", children: [hasHeadings && (jsxs("select", { className: "contentful-toolbar__select", value: getActiveHeading(), onChange: (e) => {
26572
26574
  const value = e.target.value;
26573
26575
  if (value === 'Normal text') {
26574
26576
  handleHeadingChange(0);
@@ -26577,7 +26579,7 @@ const ContentfulToolbar = ({ editor, onEmbedEntry, onEmbedAsset, disabledFeature
26577
26579
  const level = parseInt(value.replace('Heading ', ''));
26578
26580
  handleHeadingChange(level);
26579
26581
  }
26580
- }, children: [jsx("option", { value: "Normal text", children: "Normal text" }), jsx("option", { value: "Heading 1", children: "Heading 1" }), jsx("option", { value: "Heading 2", children: "Heading 2" }), jsx("option", { value: "Heading 3", children: "Heading 3" }), jsx("option", { value: "Heading 4", children: "Heading 4" }), jsx("option", { value: "Heading 5", children: "Heading 5" }), jsx("option", { value: "Heading 6", children: "Heading 6" })] })), jsx("button", { className: "contentful-toolbar__button", onClick: () => editor.chain().focus().undo().run(), disabled: !editor.can().undo(), title: "Undo", children: "\u21B6" }), jsx("button", { className: "contentful-toolbar__button", onClick: () => editor.chain().focus().redo().run(), disabled: !editor.can().redo(), title: "Redo", children: "\u21B7" })] }), jsx("div", { className: "contentful-toolbar__separator" }), jsxs("div", { className: "contentful-toolbar__group", children: [!isDisabled('bold') && (jsx("button", { className: `contentful-toolbar__button ${editor.isActive('bold') ? 'contentful-toolbar__button--active' : ''}`, onClick: () => editor.chain().focus().toggleBold().run(), title: "Bold", children: jsx("strong", { children: "B" }) })), !isDisabled('italic') && (jsx("button", { className: `contentful-toolbar__button ${editor.isActive('italic') ? 'contentful-toolbar__button--active' : ''}`, onClick: () => editor.chain().focus().toggleItalic().run(), title: "Italic", children: jsx("em", { children: "I" }) })), !isDisabled('underline') && (jsx("button", { className: `contentful-toolbar__button ${editor.isActive('underline') ? 'contentful-toolbar__button--active' : ''}`, onClick: () => editor.chain().focus().toggleUnderline().run(), title: "Underline", children: jsx("u", { children: "U" }) })), jsx("button", { className: "contentful-toolbar__button", title: "More formatting options", children: "\u22EF" }), !isDisabled('link') && (jsxs(Fragment$1, { children: [jsx("button", { className: `contentful-toolbar__button ${editor.isActive('link') ? 'contentful-toolbar__button--active' : ''}`, onClick: handleLinkToggle, title: "Link", children: "\uD83D\uDD17" }), showLinkInput && (jsxs("div", { className: "contentful-toolbar__link-input", children: [jsx("input", { type: "url", value: linkUrl, onChange: (e) => setLinkUrl(e.target.value), placeholder: "Enter URL", onKeyDown: (e) => {
26582
+ }, children: [jsx("option", { value: "Normal text", children: "Normal text" }), availableHeadings.map(level => (jsxs("option", { value: `Heading ${level}`, children: ["Heading ", level] }, level)))] })), jsx("button", { className: "contentful-toolbar__button", onClick: () => editor.chain().focus().undo().run(), disabled: !editor.can().undo(), title: "Undo", children: "\u21B6" }), jsx("button", { className: "contentful-toolbar__button", onClick: () => editor.chain().focus().redo().run(), disabled: !editor.can().redo(), title: "Redo", children: "\u21B7" })] }), jsx("div", { className: "contentful-toolbar__separator" }), jsxs("div", { className: "contentful-toolbar__group", children: [!isDisabled('bold') && isMarkAvailable('bold') && (jsx("button", { className: `contentful-toolbar__button ${editor.isActive('bold') ? 'contentful-toolbar__button--active' : ''}`, onClick: () => editor.chain().focus().toggleBold().run(), title: "Bold", children: jsx("strong", { children: "B" }) })), !isDisabled('italic') && isMarkAvailable('italic') && (jsx("button", { className: `contentful-toolbar__button ${editor.isActive('italic') ? 'contentful-toolbar__button--active' : ''}`, onClick: () => editor.chain().focus().toggleItalic().run(), title: "Italic", children: jsx("em", { children: "I" }) })), !isDisabled('underline') && isMarkAvailable('underline') && (jsx("button", { className: `contentful-toolbar__button ${editor.isActive('underline') ? 'contentful-toolbar__button--active' : ''}`, onClick: () => editor.chain().focus().toggleUnderline().run(), title: "Underline", children: jsx("u", { children: "U" }) })), jsx("button", { className: "contentful-toolbar__button", title: "More formatting options", children: "\u22EF" }), !isDisabled('link') && (jsxs(Fragment$1, { children: [jsx("button", { className: `contentful-toolbar__button ${editor.isActive('link') ? 'contentful-toolbar__button--active' : ''}`, onClick: handleLinkToggle, title: "Link", children: "\uD83D\uDD17" }), showLinkInput && (jsxs("div", { className: "contentful-toolbar__link-input", children: [jsx("input", { type: "url", value: linkUrl, onChange: (e) => setLinkUrl(e.target.value), placeholder: "Enter URL", onKeyDown: (e) => {
26581
26583
  if (e.key === 'Enter') {
26582
26584
  handleLinkSubmit();
26583
26585
  }
@@ -27268,59 +27270,63 @@ const createEmptyDocument = () => ({
27268
27270
  ],
27269
27271
  });
27270
27272
 
27271
- const ContentfulRichTextEditor = ({ initialValue, onChange, onEmbedEntry, onEmbedAsset, className = '', readonly = false, placeholder = 'Start writing...', disabledFeatures = [], theme = 'contentful' }) => {
27273
+ const ContentfulRichTextEditor = ({ initialValue, onChange, onEmbedEntry, onEmbedAsset, className = '', readonly = false, placeholder = 'Start writing...', disabledFeatures = [], theme = 'contentful', availableHeadings = [1, 2, 3, 4, 5, 6], availableMarks = ['bold', 'italic', 'underline'] }) => {
27274
+ // Build extensions array based on available features
27275
+ const extensions = [];
27276
+ // Add StarterKit with configuration
27277
+ extensions.push(StarterKit.configure({
27278
+ heading: {
27279
+ levels: availableHeadings,
27280
+ },
27281
+ bold: availableMarks.includes('bold') ? {} : false,
27282
+ italic: availableMarks.includes('italic') ? {} : false,
27283
+ bulletList: {
27284
+ HTMLAttributes: {
27285
+ class: 'contentful-bullet-list',
27286
+ },
27287
+ },
27288
+ orderedList: {
27289
+ HTMLAttributes: {
27290
+ class: 'contentful-ordered-list',
27291
+ },
27292
+ },
27293
+ blockquote: {
27294
+ HTMLAttributes: {
27295
+ class: 'contentful-blockquote',
27296
+ },
27297
+ },
27298
+ }));
27299
+ // Add underline extension only if it's in availableMarks
27300
+ if (availableMarks.includes('underline')) {
27301
+ extensions.push(Underline);
27302
+ }
27303
+ // Add other extensions
27304
+ extensions.push(Link.configure({
27305
+ openOnClick: false,
27306
+ HTMLAttributes: {
27307
+ class: 'contentful-link',
27308
+ rel: 'noopener noreferrer',
27309
+ },
27310
+ }), Table.configure({
27311
+ resizable: true,
27312
+ HTMLAttributes: {
27313
+ class: 'contentful-table',
27314
+ },
27315
+ }), TableRow.configure({
27316
+ HTMLAttributes: {
27317
+ class: 'contentful-table-row',
27318
+ },
27319
+ }), TableHeader.configure({
27320
+ HTMLAttributes: {
27321
+ class: 'contentful-table-header',
27322
+ },
27323
+ }), TableCell.configure({
27324
+ HTMLAttributes: {
27325
+ class: 'contentful-table-cell',
27326
+ },
27327
+ }));
27272
27328
  const editor = useEditor({
27273
- extensions: [
27274
- StarterKit.configure({
27275
- heading: {
27276
- levels: [1, 2, 3, 4, 5, 6],
27277
- },
27278
- bulletList: {
27279
- HTMLAttributes: {
27280
- class: 'contentful-bullet-list',
27281
- },
27282
- },
27283
- orderedList: {
27284
- HTMLAttributes: {
27285
- class: 'contentful-ordered-list',
27286
- },
27287
- },
27288
- blockquote: {
27289
- HTMLAttributes: {
27290
- class: 'contentful-blockquote',
27291
- },
27292
- },
27293
- }),
27294
- Underline,
27295
- Link.configure({
27296
- openOnClick: false,
27297
- HTMLAttributes: {
27298
- class: 'contentful-link',
27299
- rel: 'noopener noreferrer',
27300
- },
27301
- }),
27302
- Table.configure({
27303
- resizable: true,
27304
- HTMLAttributes: {
27305
- class: 'contentful-table',
27306
- },
27307
- }),
27308
- TableRow.configure({
27309
- HTMLAttributes: {
27310
- class: 'contentful-table-row',
27311
- },
27312
- }),
27313
- TableHeader.configure({
27314
- HTMLAttributes: {
27315
- class: 'contentful-table-header',
27316
- },
27317
- }),
27318
- TableCell.configure({
27319
- HTMLAttributes: {
27320
- class: 'contentful-table-cell',
27321
- },
27322
- }),
27323
- ],
27329
+ extensions,
27324
27330
  content: initialValue ? contentfulToTiptap(initialValue) : '',
27325
27331
  editable: !readonly,
27326
27332
  editorProps: {
@@ -27399,7 +27405,7 @@ const ContentfulRichTextEditor = ({ initialValue, onChange, onEmbedEntry, onEmbe
27399
27405
  if (!editor) {
27400
27406
  return (jsx("div", { className: `contentful-editor contentful-editor--loading ${className}`, children: jsx("div", { className: "contentful-editor__loading", children: "Loading editor..." }) }));
27401
27407
  }
27402
- return (jsxs("div", { className: `contentful-editor contentful-editor--${theme} ${className}`, children: [!readonly && (jsx(ContentfulToolbar, { editor: editor, onEmbedEntry: handleEmbedEntry, onEmbedAsset: handleEmbedAsset, disabledFeatures: disabledFeatures })), jsx("div", { className: "contentful-editor__content-wrapper", children: jsx(EditorContent, { editor: editor, className: "contentful-editor__content" }) })] }));
27408
+ return (jsxs("div", { className: `contentful-editor contentful-editor--${theme} ${className}`, children: [!readonly && (jsx(ContentfulToolbar, { editor: editor, onEmbedEntry: handleEmbedEntry, onEmbedAsset: handleEmbedAsset, disabledFeatures: disabledFeatures, availableHeadings: availableHeadings, availableMarks: availableMarks })), jsx("div", { className: "contentful-editor__content-wrapper", children: jsx(EditorContent, { editor: editor, className: "contentful-editor__content" }) })] }));
27403
27409
  };
27404
27410
 
27405
27411
  export { ContentfulRichTextEditor, ContentfulToolbar, contentfulToTiptap, createEmptyDocument, tiptapToContentful, validateContentfulDocument };