@carbon-labs/wc-wysiwyg 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +536 -0
  3. package/es/components/wysiwyg/src/constants.d.ts +9 -0
  4. package/es/components/wysiwyg/src/constants.js +15 -0
  5. package/es/components/wysiwyg/src/constants.js.map +1 -0
  6. package/es/components/wysiwyg/src/extensions/alignment.d.ts +16 -0
  7. package/es/components/wysiwyg/src/extensions/alignment.js +97 -0
  8. package/es/components/wysiwyg/src/extensions/alignment.js.map +1 -0
  9. package/es/components/wysiwyg/src/extensions/blocks.d.ts +13 -0
  10. package/es/components/wysiwyg/src/extensions/blocks.js +92 -0
  11. package/es/components/wysiwyg/src/extensions/blocks.js.map +1 -0
  12. package/es/components/wysiwyg/src/extensions/button-helper.d.ts +62 -0
  13. package/es/components/wysiwyg/src/extensions/button-helper.js +70 -0
  14. package/es/components/wysiwyg/src/extensions/button-helper.js.map +1 -0
  15. package/es/components/wysiwyg/src/extensions/clipboard.d.ts +9 -0
  16. package/es/components/wysiwyg/src/extensions/clipboard.js +59 -0
  17. package/es/components/wysiwyg/src/extensions/clipboard.js.map +1 -0
  18. package/es/components/wysiwyg/src/extensions/history.d.ts +9 -0
  19. package/es/components/wysiwyg/src/extensions/history.js +56 -0
  20. package/es/components/wysiwyg/src/extensions/history.js.map +1 -0
  21. package/es/components/wysiwyg/src/extensions/insert.d.ts +13 -0
  22. package/es/components/wysiwyg/src/extensions/insert.js +301 -0
  23. package/es/components/wysiwyg/src/extensions/insert.js.map +1 -0
  24. package/es/components/wysiwyg/src/extensions/lists.d.ts +9 -0
  25. package/es/components/wysiwyg/src/extensions/lists.js +88 -0
  26. package/es/components/wysiwyg/src/extensions/lists.js.map +1 -0
  27. package/es/components/wysiwyg/src/extensions/popover-utils.d.ts +26 -0
  28. package/es/components/wysiwyg/src/extensions/popover-utils.js +68 -0
  29. package/es/components/wysiwyg/src/extensions/popover-utils.js.map +1 -0
  30. package/es/components/wysiwyg/src/extensions/search.d.ts +10 -0
  31. package/es/components/wysiwyg/src/extensions/search.js +238 -0
  32. package/es/components/wysiwyg/src/extensions/search.js.map +1 -0
  33. package/es/components/wysiwyg/src/extensions/tables.d.ts +12 -0
  34. package/es/components/wysiwyg/src/extensions/tables.js +120 -0
  35. package/es/components/wysiwyg/src/extensions/tables.js.map +1 -0
  36. package/es/components/wysiwyg/src/extensions/text-color.d.ts +13 -0
  37. package/es/components/wysiwyg/src/extensions/text-color.js +159 -0
  38. package/es/components/wysiwyg/src/extensions/text-color.js.map +1 -0
  39. package/es/components/wysiwyg/src/extensions/text-formatting.d.ts +9 -0
  40. package/es/components/wysiwyg/src/extensions/text-formatting.js +93 -0
  41. package/es/components/wysiwyg/src/extensions/text-formatting.js.map +1 -0
  42. package/es/components/wysiwyg/src/extensions/typeface.d.ts +9 -0
  43. package/es/components/wysiwyg/src/extensions/typeface.js +79 -0
  44. package/es/components/wysiwyg/src/extensions/typeface.js.map +1 -0
  45. package/es/components/wysiwyg/src/extensions/typography.d.ts +9 -0
  46. package/es/components/wysiwyg/src/extensions/typography.js +88 -0
  47. package/es/components/wysiwyg/src/extensions/typography.js.map +1 -0
  48. package/es/components/wysiwyg/src/roving-tabindex.d.ts +24 -0
  49. package/es/components/wysiwyg/src/roving-tabindex.js +148 -0
  50. package/es/components/wysiwyg/src/roving-tabindex.js.map +1 -0
  51. package/es/components/wysiwyg/src/types.d.ts +57 -0
  52. package/es/components/wysiwyg/src/types.js +18 -0
  53. package/es/components/wysiwyg/src/types.js.map +1 -0
  54. package/es/components/wysiwyg/src/wysiwyg.scss.js +6 -0
  55. package/es/components/wysiwyg/src/wysiwyg.scss.js.map +1 -0
  56. package/es/components/wysiwyg/src/wysiwyg.template.d.ts +38 -0
  57. package/es/components/wysiwyg/src/wysiwyg.template.js +116 -0
  58. package/es/components/wysiwyg/src/wysiwyg.template.js.map +1 -0
  59. package/es/components/wysiwyg/wysiwyg.d.ts +20 -0
  60. package/es/components/wysiwyg/wysiwyg.js +26 -0
  61. package/es/components/wysiwyg/wysiwyg.js.map +1 -0
  62. package/es/index.d.ts +22 -0
  63. package/es/index.js +16 -0
  64. package/es/index.js.map +1 -0
  65. package/lib/components/wysiwyg/src/constants.d.ts +9 -0
  66. package/lib/components/wysiwyg/src/constants.js +19 -0
  67. package/lib/components/wysiwyg/src/constants.js.map +1 -0
  68. package/lib/components/wysiwyg/src/extensions/alignment.d.ts +16 -0
  69. package/lib/components/wysiwyg/src/extensions/alignment.js +99 -0
  70. package/lib/components/wysiwyg/src/extensions/alignment.js.map +1 -0
  71. package/lib/components/wysiwyg/src/extensions/blocks.d.ts +13 -0
  72. package/lib/components/wysiwyg/src/extensions/blocks.js +94 -0
  73. package/lib/components/wysiwyg/src/extensions/blocks.js.map +1 -0
  74. package/lib/components/wysiwyg/src/extensions/button-helper.d.ts +62 -0
  75. package/lib/components/wysiwyg/src/extensions/button-helper.js +73 -0
  76. package/lib/components/wysiwyg/src/extensions/button-helper.js.map +1 -0
  77. package/lib/components/wysiwyg/src/extensions/clipboard.d.ts +9 -0
  78. package/lib/components/wysiwyg/src/extensions/clipboard.js +61 -0
  79. package/lib/components/wysiwyg/src/extensions/clipboard.js.map +1 -0
  80. package/lib/components/wysiwyg/src/extensions/history.d.ts +9 -0
  81. package/lib/components/wysiwyg/src/extensions/history.js +58 -0
  82. package/lib/components/wysiwyg/src/extensions/history.js.map +1 -0
  83. package/lib/components/wysiwyg/src/extensions/insert.d.ts +13 -0
  84. package/lib/components/wysiwyg/src/extensions/insert.js +303 -0
  85. package/lib/components/wysiwyg/src/extensions/insert.js.map +1 -0
  86. package/lib/components/wysiwyg/src/extensions/lists.d.ts +9 -0
  87. package/lib/components/wysiwyg/src/extensions/lists.js +90 -0
  88. package/lib/components/wysiwyg/src/extensions/lists.js.map +1 -0
  89. package/lib/components/wysiwyg/src/extensions/popover-utils.d.ts +26 -0
  90. package/lib/components/wysiwyg/src/extensions/popover-utils.js +72 -0
  91. package/lib/components/wysiwyg/src/extensions/popover-utils.js.map +1 -0
  92. package/lib/components/wysiwyg/src/extensions/search.d.ts +10 -0
  93. package/lib/components/wysiwyg/src/extensions/search.js +240 -0
  94. package/lib/components/wysiwyg/src/extensions/search.js.map +1 -0
  95. package/lib/components/wysiwyg/src/extensions/tables.d.ts +12 -0
  96. package/lib/components/wysiwyg/src/extensions/tables.js +122 -0
  97. package/lib/components/wysiwyg/src/extensions/tables.js.map +1 -0
  98. package/lib/components/wysiwyg/src/extensions/text-color.d.ts +13 -0
  99. package/lib/components/wysiwyg/src/extensions/text-color.js +161 -0
  100. package/lib/components/wysiwyg/src/extensions/text-color.js.map +1 -0
  101. package/lib/components/wysiwyg/src/extensions/text-formatting.d.ts +9 -0
  102. package/lib/components/wysiwyg/src/extensions/text-formatting.js +95 -0
  103. package/lib/components/wysiwyg/src/extensions/text-formatting.js.map +1 -0
  104. package/lib/components/wysiwyg/src/extensions/typeface.d.ts +9 -0
  105. package/lib/components/wysiwyg/src/extensions/typeface.js +81 -0
  106. package/lib/components/wysiwyg/src/extensions/typeface.js.map +1 -0
  107. package/lib/components/wysiwyg/src/extensions/typography.d.ts +9 -0
  108. package/lib/components/wysiwyg/src/extensions/typography.js +90 -0
  109. package/lib/components/wysiwyg/src/extensions/typography.js.map +1 -0
  110. package/lib/components/wysiwyg/src/roving-tabindex.d.ts +24 -0
  111. package/lib/components/wysiwyg/src/roving-tabindex.js +148 -0
  112. package/lib/components/wysiwyg/src/roving-tabindex.js.map +1 -0
  113. package/lib/components/wysiwyg/src/types.d.ts +57 -0
  114. package/lib/components/wysiwyg/src/types.js +20 -0
  115. package/lib/components/wysiwyg/src/types.js.map +1 -0
  116. package/lib/components/wysiwyg/src/wysiwyg.scss.js +10 -0
  117. package/lib/components/wysiwyg/src/wysiwyg.scss.js.map +1 -0
  118. package/lib/components/wysiwyg/src/wysiwyg.template.d.ts +38 -0
  119. package/lib/components/wysiwyg/src/wysiwyg.template.js +120 -0
  120. package/lib/components/wysiwyg/src/wysiwyg.template.js.map +1 -0
  121. package/lib/components/wysiwyg/wysiwyg.d.ts +20 -0
  122. package/lib/components/wysiwyg/wysiwyg.js +30 -0
  123. package/lib/components/wysiwyg/wysiwyg.js.map +1 -0
  124. package/lib/index.d.ts +22 -0
  125. package/lib/index.js +38 -0
  126. package/lib/index.js.map +1 -0
  127. package/package.json +88 -0
package/README.md ADDED
@@ -0,0 +1,536 @@
1
+ <p align="center">
2
+ <a href="https://www.carbondesignsystem.com">
3
+ <img alt="Carbon Design System" src="https://user-images.githubusercontent.com/3901764/57545698-ce5f2380-7320-11e9-8682-903df232d7b0.png" width="100%" />
4
+ </a>
5
+ </p>
6
+ <h1 align="center">
7
+ Carbon Labs WYSIWYG Editor
8
+ </h1>
9
+
10
+ > A rich text editor component built with TipTap and Carbon Design System
11
+
12
+ ## Overview
13
+
14
+ The WYSIWYG (What You See Is What You Get) editor is a comprehensive rich text
15
+ editing component that provides a full-featured editing experience with Carbon
16
+ Design System styling. Built on [TipTap](https://tiptap.dev/), it offers
17
+ extensibility, accessibility, and seamless integration with Carbon components.
18
+
19
+ ## Features
20
+
21
+ - **Rich Text Editing** - Bold, italic, underline, strikethrough, inline code
22
+ - **Typography** - Six heading levels and paragraph formatting
23
+ - **Lists** - Bullet lists, numbered lists, and interactive task lists
24
+ - **Tables** - Full table editing with merge/split and row/column operations
25
+ - **Styling** - Text alignment, colors using Carbon tokens, highlighting
26
+ - **Search** - Real-time in-editor search with match highlighting
27
+ - **Code & Quotes** - Code blocks and blockquotes
28
+ - **Media** - Insert and edit links and images with resizing
29
+ - **Source Editing** - Toggle between visual, HTML, and Markdown modes
30
+ - **History** - Full undo/redo with keyboard shortcuts
31
+ - **Accessible** - Keyboard navigation, ARIA labels, screen reader support
32
+ - **Extensible** - Built on TipTap's extension system
33
+
34
+ ## Getting started
35
+
36
+ ### Installation
37
+
38
+ Install `@carbon-labs/wc-wysiwyg` to use this component.
39
+
40
+ ```bash
41
+ npm install @carbon-labs/wc-wysiwyg
42
+ ```
43
+
44
+ or
45
+
46
+ ```bash
47
+ yarn add @carbon-labs/wc-wysiwyg
48
+ ```
49
+
50
+ ### Basic Usage
51
+
52
+ ```javascript
53
+ import '@carbon-labs/wc-wysiwyg/es/index.js';
54
+ import {
55
+ History,
56
+ TextFormatting,
57
+ Typography,
58
+ Lists,
59
+ } from '@carbon-labs/wc-wysiwyg/es/index.js';
60
+
61
+ // Get the editor element
62
+ const editor = document.querySelector('clabs-wysiwyg');
63
+
64
+ // Configure extensions
65
+ editor.extensions = [History, TextFormatting, Typography, Lists];
66
+
67
+ // Set initial content
68
+ editor.content = '<p>Start typing...</p>';
69
+
70
+ // Listen for changes
71
+ editor.addEventListener('content-change', (e) => {
72
+ console.log('Content:', e.detail.content);
73
+ });
74
+ ```
75
+
76
+ ### HTML
77
+
78
+ ```html
79
+ <clabs-wysiwyg toolbar-size="md" content="<p>Initial content</p>">
80
+ </clabs-wysiwyg>
81
+ ```
82
+
83
+ ## Extensions
84
+
85
+ The editor's functionality is provided through extensions. Import and use only
86
+ the extensions you need:
87
+
88
+ ### Core Extensions
89
+
90
+ ```javascript
91
+ import {
92
+ History, // Undo/redo
93
+ TextFormatting, // Bold, italic, underline, etc.
94
+ Typography, // Headings and paragraphs
95
+ } from '@carbon-labs/wc-wysiwyg/es/index.js';
96
+ ```
97
+
98
+ ### List Extensions
99
+
100
+ ```javascript
101
+ import {
102
+ Lists, // Bullet, numbered, and task lists
103
+ } from '@carbon-labs/wc-wysiwyg/es/index.js';
104
+ ```
105
+
106
+ ### Advanced Extensions
107
+
108
+ ```javascript
109
+ import {
110
+ Tables, // Table editing
111
+ Alignment, // Text alignment
112
+ TextColor, // Colors and highlighting
113
+ Search, // In-editor search
114
+ Blocks, // Code blocks and blockquotes
115
+ Insert, // Links and images
116
+ Typeface, // Font family selection
117
+ } from '@carbon-labs/wc-wysiwyg/es/index.js';
118
+ ```
119
+
120
+ ### Source Editing Extensions
121
+
122
+ ```javascript
123
+ import {
124
+ Html, // HTML source editing
125
+ Markdown, // Markdown editing
126
+ } from '@carbon-labs/wc-wysiwyg/es/index.js';
127
+ ```
128
+
129
+ ### Complete Example
130
+
131
+ ```javascript
132
+ import '@carbon-labs/wc-wysiwyg/es/index.js';
133
+ import {
134
+ History,
135
+ TextFormatting,
136
+ Typography,
137
+ Lists,
138
+ Tables,
139
+ Alignment,
140
+ TextColor,
141
+ Search,
142
+ Html,
143
+ Markdown,
144
+ Blocks,
145
+ Insert,
146
+ Typeface,
147
+ } from '@carbon-labs/wc-wysiwyg/es/index.js';
148
+
149
+ const editor = document.querySelector('clabs-wysiwyg');
150
+
151
+ // Use all extensions
152
+ editor.extensions = [
153
+ History,
154
+ TextFormatting,
155
+ Typography,
156
+ Lists,
157
+ Tables,
158
+ Alignment,
159
+ TextColor,
160
+ Search,
161
+ Html,
162
+ Markdown,
163
+ Blocks,
164
+ Insert,
165
+ Typeface,
166
+ ];
167
+ ```
168
+
169
+ ## API
170
+
171
+ ### Properties
172
+
173
+ | Property | Type | Default | Description |
174
+ | ------------- | ---------------------- | ------- | -------------------------- |
175
+ | `content` | `string` | `''` | HTML content of the editor |
176
+ | `extensions` | `Array<Extension>` | `[]` | Array of extension objects |
177
+ | `toolbarSize` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of toolbar buttons |
178
+
179
+ ### Events
180
+
181
+ #### `content-change`
182
+
183
+ Fired when editor content changes.
184
+
185
+ **Event Detail:**
186
+
187
+ ```typescript
188
+ {
189
+ content: string; // HTML content
190
+ markdown: string; // Markdown (if Markdown extension enabled)
191
+ }
192
+ ```
193
+
194
+ **Example:**
195
+
196
+ ```javascript
197
+ editor.addEventListener('content-change', (event) => {
198
+ const { content, markdown } = event.detail;
199
+ console.log('HTML:', content);
200
+ console.log('Markdown:', markdown);
201
+ });
202
+ ```
203
+
204
+ ### Methods
205
+
206
+ The editor exposes the TipTap editor instance through the `editor` property:
207
+
208
+ ```javascript
209
+ const editorInstance = document.querySelector('clabs-wysiwyg').editor;
210
+
211
+ // Get content
212
+ const html = editorInstance.getHTML();
213
+ const json = editorInstance.getJSON();
214
+
215
+ // Set content
216
+ editorInstance.commands.setContent('<p>New content</p>');
217
+
218
+ // Execute commands
219
+ editorInstance.chain().focus().toggleBold().run();
220
+ ```
221
+
222
+ ## Extension Details
223
+
224
+ ### History
225
+
226
+ Provides undo/redo functionality with keyboard shortcuts.
227
+
228
+ **Keyboard Shortcuts:**
229
+
230
+ - `Ctrl+Z` / `Cmd+Z` - Undo
231
+ - `Ctrl+Shift+Z` / `Cmd+Shift+Z` - Redo
232
+
233
+ ### TextFormatting
234
+
235
+ Basic text formatting options.
236
+
237
+ **Features:**
238
+
239
+ - Bold (`Ctrl+B` / `Cmd+B`)
240
+ - Italic (`Ctrl+I` / `Cmd+I`)
241
+ - Underline (`Ctrl+U` / `Cmd+U`)
242
+ - Strikethrough
243
+ - Inline code
244
+
245
+ ### Typography
246
+
247
+ Heading levels and paragraph formatting.
248
+
249
+ **Features:**
250
+
251
+ - Heading 1-6
252
+ - Paragraph
253
+ - Dropdown selector
254
+
255
+ ### Lists
256
+
257
+ List formatting with nesting support.
258
+
259
+ **Features:**
260
+
261
+ - Bullet lists
262
+ - Numbered lists
263
+ - Task lists (checkboxes)
264
+ - Indent/outdent
265
+
266
+ ### Tables
267
+
268
+ Complete table editing capabilities.
269
+
270
+ **Features:**
271
+
272
+ - Insert tables
273
+ - Add/delete rows and columns
274
+ - Merge/split cells
275
+ - Resizable columns
276
+
277
+ ### Alignment
278
+
279
+ Text alignment options.
280
+
281
+ **Features:**
282
+
283
+ - Left align
284
+ - Center align
285
+ - Right align
286
+ - Justify
287
+
288
+ ### TextColor
289
+
290
+ Text colors and highlighting using Carbon tokens.
291
+
292
+ **Features:**
293
+
294
+ - Primary/secondary text colors
295
+ - Link colors
296
+ - Status colors (success, error, warning, info)
297
+ - Text highlighting
298
+ - Semantic marks (insert, delete)
299
+
300
+ ### Search
301
+
302
+ Real-time search within the editor.
303
+
304
+ **Features:**
305
+
306
+ - Live search as you type
307
+ - Match highlighting
308
+ - Match count display
309
+ - Case-insensitive
310
+
311
+ ### Html
312
+
313
+ HTML source editing mode.
314
+
315
+ **Features:**
316
+
317
+ - Toggle to HTML view
318
+ - Syntax formatting
319
+ - Direct HTML editing
320
+
321
+ ### Markdown
322
+
323
+ Markdown editing mode.
324
+
325
+ **Features:**
326
+
327
+ - Toggle to Markdown view
328
+ - Full Markdown syntax support
329
+ - Converts between Markdown and HTML
330
+
331
+ ### Blocks
332
+
333
+ Code blocks and blockquotes.
334
+
335
+ **Features:**
336
+
337
+ - Code blocks with syntax preservation
338
+ - Blockquotes
339
+ - Citation support
340
+
341
+ ### Insert
342
+
343
+ Insert links and images.
344
+
345
+ **Features:**
346
+
347
+ - Link insertion and editing
348
+ - Image insertion by URL
349
+ - Image resizing with drag handles
350
+ - Link validation
351
+
352
+ ### Typeface
353
+
354
+ Font family selection.
355
+
356
+ **Features:**
357
+
358
+ - IBM Plex Sans (default)
359
+ - IBM Plex Serif
360
+ - IBM Plex Mono
361
+ - Common system fonts
362
+
363
+ ## Creating Custom Extensions
364
+
365
+ You can create custom extensions using TipTap's extension API:
366
+
367
+ ```javascript
368
+ import { Extension, Mark } from '@tiptap/core';
369
+ import { html } from 'lit';
370
+
371
+ // Create a custom mark
372
+ const HighlightMark = Mark.create({
373
+ name: 'highlight',
374
+
375
+ parseHTML() {
376
+ return [{ tag: 'mark' }];
377
+ },
378
+
379
+ renderHTML({ HTMLAttributes }) {
380
+ return ['mark', HTMLAttributes, 0];
381
+ },
382
+ });
383
+
384
+ // Create extension
385
+ const HighlightExtension = Extension.create({
386
+ name: 'highlightExtension',
387
+ addExtensions: () => [HighlightMark],
388
+ });
389
+
390
+ // Add toolbar UI
391
+ HighlightExtension.toolbarRender = (editor, toolbarSize) => {
392
+ return html`
393
+ <div class="clabs-wysiwyg__toolbar-group">
394
+ <cds-icon-button
395
+ kind="ghost"
396
+ .size=${toolbarSize}
397
+ @click=${() => editor?.chain().focus().toggleMark('highlight').run()}>
398
+ <span slot="tooltip-content">Highlight</span>
399
+ </cds-icon-button>
400
+ </div>
401
+ `;
402
+ };
403
+
404
+ // Use it
405
+ editor.extensions = [HighlightExtension, ...otherExtensions];
406
+ ```
407
+
408
+ ## Styling
409
+
410
+ The editor uses Carbon Design System tokens. You can customize appearance using
411
+ CSS custom properties:
412
+
413
+ ```css
414
+ clabs-wysiwyg {
415
+ /* Override Carbon tokens */
416
+ --cds-layer-01: #f4f4f4;
417
+ --cds-text-primary: #161616;
418
+ --cds-border-strong: #8d8d8d;
419
+ }
420
+ ```
421
+
422
+ ## Accessibility
423
+
424
+ The editor is built with accessibility in mind:
425
+
426
+ - ✅ Keyboard navigation for all controls
427
+ - ✅ ARIA labels on interactive elements
428
+ - ✅ Descriptive tooltips
429
+ - ✅ Proper focus management
430
+ - ✅ Screen reader support
431
+ - ✅ Semantic HTML output
432
+
433
+ ## Browser Support
434
+
435
+ - Chrome/Edge (latest)
436
+ - Firefox (latest)
437
+ - Safari (latest)
438
+ - Mobile browsers (iOS Safari, Chrome Mobile)
439
+
440
+ ## Performance Tips
441
+
442
+ For optimal performance with large documents:
443
+
444
+ 1. Use only the extensions you need
445
+ 2. Consider pagination for very long documents
446
+ 3. Disable real-time search for documents >10,000 words
447
+ 4. Limit history depth if needed
448
+
449
+ ## Examples
450
+
451
+ ### Minimal Editor
452
+
453
+ ```javascript
454
+ import '@carbon-labs/wc-wysiwyg/es/index.js';
455
+ import {
456
+ History,
457
+ TextFormatting,
458
+ Typography,
459
+ } from '@carbon-labs/wc-wysiwyg/es/index.js';
460
+
461
+ editor.extensions = [History, TextFormatting, Typography];
462
+ ```
463
+
464
+ ### Full-Featured Editor
465
+
466
+ ```javascript
467
+ import '@carbon-labs/wc-wysiwyg/es/index.js';
468
+ import {
469
+ History,
470
+ TextFormatting,
471
+ Typography,
472
+ Lists,
473
+ Tables,
474
+ Alignment,
475
+ TextColor,
476
+ Search,
477
+ Html,
478
+ Markdown,
479
+ Blocks,
480
+ Insert,
481
+ } from '@carbon-labs/wc-wysiwyg/es/index.js';
482
+
483
+ editor.extensions = [
484
+ History,
485
+ TextFormatting,
486
+ Typography,
487
+ Lists,
488
+ Tables,
489
+ Alignment,
490
+ TextColor,
491
+ Search,
492
+ Html,
493
+ Markdown,
494
+ Blocks,
495
+ Insert,
496
+ ];
497
+ ```
498
+
499
+ ### With Event Handling
500
+
501
+ ```javascript
502
+ const editor = document.querySelector('clabs-wysiwyg');
503
+
504
+ editor.addEventListener('content-change', (e) => {
505
+ // Auto-save
506
+ localStorage.setItem('draft', e.detail.content);
507
+
508
+ // Update character count
509
+ const text = e.detail.content.replace(/<[^>]*>/g, '');
510
+ document.getElementById('char-count').textContent = text.length;
511
+ });
512
+ ```
513
+
514
+ ## Storybook
515
+
516
+ You can view the current state of the component in our
517
+ [Storybook](https://labs.carbondesignsystem.com/web-components/).
518
+
519
+ ## Contributing
520
+
521
+ We welcome contributions! Please see our
522
+ [contributing guidelines](https://github.com/carbon-design-system/carbon-labs/blob/main/CONTRIBUTING.md).
523
+
524
+ ## 📝 License
525
+
526
+ Licensed under the
527
+ [Apache 2.0 License](https://github.com/carbon-design-system/carbon-labs/blob/main/LICENSE).
528
+
529
+ ## <picture><source height="20" width="20" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/ibm-telemetry/telemetry-js/main/docs/images/ibm-telemetry-dark.svg"><source height="20" width="20" media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/ibm-telemetry/telemetry-js/main/docs/images/ibm-telemetry-light.svg"><img height="20" width="20" alt="IBM Telemetry" src="https://raw.githubusercontent.com/ibm-telemetry/telemetry-js/main/docs/images/ibm-telemetry-light.svg"></picture> IBM Telemetry
530
+
531
+ This package uses IBM Telemetry to collect de-identified and anonymized metrics
532
+ data. By installing this package as a dependency you are agreeing to telemetry
533
+ collection. To opt out, see
534
+ [Opting out of IBM Telemetry data collection](https://github.com/ibm-telemetry/telemetry-js/tree/main#opting-out-of-ibm-telemetry-data-collection).
535
+ For more information on the data being collected, please see the
536
+ [IBM Telemetry documentation](https://github.com/ibm-telemetry/telemetry-js/tree/main#ibm-telemetry-collection-basics).
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright IBM Corp. 2026
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ export declare const TOOLTIP_ENTER_DELAY_MS = 400;
8
+ export declare const TOOLTIP_LEAVE_DELAY_MS = 100;
9
+ export declare const BASE_CLASS: string;
@@ -0,0 +1,15 @@
1
+ import { settings } from '@carbon-labs/utilities';
2
+
3
+ /**
4
+ * Copyright IBM Corp. 2026
5
+ *
6
+ * This source code is licensed under the Apache-2.0 license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ const { stablePrefix: clabsPrefix } = settings;
10
+ const TOOLTIP_ENTER_DELAY_MS = 400;
11
+ const TOOLTIP_LEAVE_DELAY_MS = 100;
12
+ const BASE_CLASS = `${clabsPrefix}-wysiwyg`;
13
+
14
+ export { BASE_CLASS, TOOLTIP_ENTER_DELAY_MS, TOOLTIP_LEAVE_DELAY_MS };
15
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../../../../../components/wysiwyg/src/constants.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAAA;;;;;AAKG;AAGH,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,QAAQ;AAEvC,MAAM,sBAAsB,GAAG;AAC/B,MAAM,sBAAsB,GAAG;AAE/B,MAAM,UAAU,GAAG,CAAA,EAAG,WAAW;;;;"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copyright IBM Corp. 2026
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import '@carbon/web-components/es/components/icon-button/index.js';
8
+ import '@carbon/web-components/es/components/popover/index.js';
9
+ import '@carbon/web-components/es/components/layer/index.js';
10
+ import type { ExtensionWithToolbar } from '../types.js';
11
+ import '../roving-tabindex.js';
12
+ /**
13
+ * Alignment extension for text alignment controls (left, center, right, justify).
14
+ * Provides a toolbar with a popover containing alignment options.
15
+ */
16
+ export declare const Alignment: ExtensionWithToolbar;
@@ -0,0 +1,97 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import { html } from 'lit';
3
+ import { createRef, ref } from 'lit/directives/ref.js';
4
+ import TextAlignLeft from '@carbon/icons/es/text--align--left/16.js';
5
+ import TextAlignCenter from '@carbon/icons/es/text--align--center/16.js';
6
+ import TextAlignRight from '@carbon/icons/es/text--align--right/16.js';
7
+ import TextAlignJustify from '@carbon/icons/es/text--align--justify/16.js';
8
+ import '@carbon/web-components/es/components/icon-button/index.js';
9
+ import '@carbon/web-components/es/components/popover/index.js';
10
+ import '@carbon/web-components/es/components/layer/index.js';
11
+ import { BASE_CLASS } from '../constants.js';
12
+ import { iconButton, cmdButton } from './button-helper.js';
13
+ import { togglePopover, setupPopoverContent, closePopover } from './popover-utils.js';
14
+ import '../roving-tabindex.js';
15
+ import TextAlign from '@tiptap/extension-text-align';
16
+
17
+ /**
18
+ * Copyright IBM Corp. 2026
19
+ *
20
+ * This source code is licensed under the Apache-2.0 license found in the
21
+ * LICENSE file in the root directory of this source tree.
22
+ */
23
+ const styles = `
24
+ .${BASE_CLASS}__alignment-popover-content[open]::part(content) {
25
+ display: flex;
26
+ }
27
+ `;
28
+ const ALIGNMENTS = [
29
+ ['left', TextAlignLeft, 'Align Left'],
30
+ ['center', TextAlignCenter, 'Align Center'],
31
+ ['right', TextAlignRight, 'Align Right'],
32
+ ['justify', TextAlignJustify, 'Justify'],
33
+ ];
34
+ /**
35
+ * Alignment extension for text alignment controls (left, center, right, justify).
36
+ * Provides a toolbar with a popover containing alignment options.
37
+ */
38
+ const Alignment = Extension.create({
39
+ name: 'alignment',
40
+ /** Adds the TextAlign extension with configured alignment options */
41
+ addExtensions: () => [
42
+ TextAlign.configure({
43
+ types: ['heading', 'paragraph'],
44
+ alignments: ALIGNMENTS.map(([alignment]) => alignment),
45
+ defaultAlignment: 'left',
46
+ }),
47
+ ],
48
+ });
49
+ /**
50
+ * Renders the alignment toolbar with popover controls.
51
+ * @param {Editor | null} editor - The TipTap editor instance
52
+ * @param {ToolbarSize} toolbarSize - Size of the toolbar buttons
53
+ */
54
+ Alignment.toolbarRender = (editor, toolbarSize = 'md') => {
55
+ var _a;
56
+ const popover = createRef();
57
+ /** Close popover and re-render toolbar to reflect the new alignment */
58
+ const onDone = () => {
59
+ var _a, _b;
60
+ closePopover(popover);
61
+ (_b = (_a = editor === null || editor === void 0 ? void 0 : editor.component) === null || _a === void 0 ? void 0 : _a.requestUpdate) === null || _b === void 0 ? void 0 : _b.call(_a);
62
+ };
63
+ const [, icon] = (_a = ALIGNMENTS.find(([alignment]) => editor === null || editor === void 0 ? void 0 : editor.isActive({ textAlign: alignment }))) !== null && _a !== void 0 ? _a : ALIGNMENTS[0];
64
+ return html `
65
+ <style>
66
+ ${styles}
67
+ </style>
68
+ <div class="${BASE_CLASS}__toolbar-group">
69
+ <cds-layer>
70
+ <cds-popover ${ref(popover)} tabtip align="bottom" autoalign>
71
+ ${iconButton(icon, () => togglePopover(popover), toolbarSize, {
72
+ disabled: !(editor === null || editor === void 0 ? void 0 : editor.can().setTextAlign('left')),
73
+ tooltip: 'Text Alignment',
74
+ caret: true,
75
+ iconTabIndex: '-1',
76
+ })}
77
+ <cds-popover-content
78
+ slot="content"
79
+ class="${BASE_CLASS}__alignment-popover-content"
80
+ ${ref(setupPopoverContent)}>
81
+ <clabs-roving-tabindex>
82
+ ${ALIGNMENTS.map(([alignment, icon, tooltip]) => cmdButton(icon, editor, 'setTextAlign', toolbarSize, {
83
+ args: [alignment],
84
+ active: { textAlign: alignment },
85
+ tooltip,
86
+ onDone,
87
+ }))}
88
+ </clabs-roving-tabindex>
89
+ </cds-popover-content>
90
+ </cds-popover>
91
+ </cds-layer>
92
+ </div>
93
+ `;
94
+ };
95
+
96
+ export { Alignment };
97
+ //# sourceMappingURL=alignment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alignment.js","sources":["../../../../../../components/wysiwyg/src/extensions/alignment.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;AAKG;AAwBH,MAAM,MAAM,GAAG;KACV,UAAU,CAAA;;;CAGd;AAED,MAAM,UAAU,GAAG;AACjB,IAAA,CAAC,MAAM,EAAE,aAAa,EAAE,YAAY,CAAC;AACrC,IAAA,CAAC,QAAQ,EAAE,eAAe,EAAE,cAAc,CAAC;AAC3C,IAAA,CAAC,OAAO,EAAE,cAAc,EAAE,aAAa,CAAC;AACxC,IAAA,CAAC,SAAS,EAAE,gBAAgB,EAAE,SAAS,CAAC;CAChC;AAEV;;;AAGG;AACI,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC;AACxC,IAAA,IAAI,EAAE,WAAW;;IAEjB,aAAa,EAAE,MAAM;QACnB,SAAS,CAAC,SAAS,CAAC;AAClB,YAAA,KAAK,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC;AAC/B,YAAA,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC;AACtD,YAAA,gBAAgB,EAAE,MAAM;SACzB,CAAC;AACH,KAAA;AACF,CAAA;AAED;;;;AAIG;AACH,SAAS,CAAC,aAAa,GAAG,CACxB,MAAqB,EACrB,WAAA,GAA2B,IAAI,KAC7B;;AACF,IAAA,MAAM,OAAO,GAAG,SAAS,EAAO;;IAEhC,MAAM,MAAM,GAAG,MAAK;;QAClB,YAAY,CAAC,OAAO,CAAC;QACrB,CAAA,EAAA,GAAA,CAAA,EAAA,GAAC,MAAc,KAAA,IAAA,IAAd,MAAM,KAAA,MAAA,GAAA,MAAA,GAAN,MAAM,CAAU,SAAS,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,aAAa,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,EAAA,CAAI;AAC/C,IAAA,CAAC;AAED,IAAA,MAAM,GAAG,IAAI,CAAC,GACZ,MAAA,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAC1B,MAAM,KAAA,IAAA,IAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAC3C,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,EAAA,GAAI,UAAU,CAAC,CAAC,CAAC;AAEpB,IAAA,OAAO,IAAI,CAAA;;QAEL,MAAM;;kBAEI,UAAU,CAAA;;uBAEL,GAAG,CAAC,OAAO,CAAC,CAAA;AACvB,UAAA,EAAA,UAAU,CAAC,IAAI,EAAE,MAAM,aAAa,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE;AAC5D,QAAA,QAAQ,EAAE,EAAC,MAAM,aAAN,MAAM,KAAA,MAAA,GAAA,MAAA,GAAN,MAAM,CAAE,GAAG,EAAA,CAAG,YAAY,CAAC,MAAM,CAAC,CAAA;AAC7C,QAAA,OAAO,EAAE,gBAAgB;AACzB,QAAA,KAAK,EAAE,IAAI;AACX,QAAA,YAAY,EAAE,IAAI;KACnB,CAAC;;;qBAGS,UAAU,CAAA;cACjB,GAAG,CAAC,mBAAmB,CAAC,CAAA;;gBAEtB,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,KAC1C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE;QACnD,IAAI,EAAE,CAAC,SAAS,CAAC;AACjB,QAAA,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE;QAChC,OAAO;QACP,MAAM;AACP,KAAA,CAAC,CACH;;;;;;GAMZ;AACH,CAAC;;;;"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright IBM Corp. 2026
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import '@carbon/web-components/es/components/icon-button/index.js';
8
+ import type { ExtensionWithToolbar } from '../types.js';
9
+ /**
10
+ * Blocks extension for code blocks and blockquotes.
11
+ * Provides toolbar controls for inserting code blocks and blockquotes.
12
+ */
13
+ export declare const Blocks: ExtensionWithToolbar;