@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.
- package/LICENSE +201 -0
- package/README.md +536 -0
- package/es/components/wysiwyg/src/constants.d.ts +9 -0
- package/es/components/wysiwyg/src/constants.js +15 -0
- package/es/components/wysiwyg/src/constants.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/alignment.d.ts +16 -0
- package/es/components/wysiwyg/src/extensions/alignment.js +97 -0
- package/es/components/wysiwyg/src/extensions/alignment.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/blocks.d.ts +13 -0
- package/es/components/wysiwyg/src/extensions/blocks.js +92 -0
- package/es/components/wysiwyg/src/extensions/blocks.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/button-helper.d.ts +62 -0
- package/es/components/wysiwyg/src/extensions/button-helper.js +70 -0
- package/es/components/wysiwyg/src/extensions/button-helper.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/clipboard.d.ts +9 -0
- package/es/components/wysiwyg/src/extensions/clipboard.js +59 -0
- package/es/components/wysiwyg/src/extensions/clipboard.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/history.d.ts +9 -0
- package/es/components/wysiwyg/src/extensions/history.js +56 -0
- package/es/components/wysiwyg/src/extensions/history.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/insert.d.ts +13 -0
- package/es/components/wysiwyg/src/extensions/insert.js +301 -0
- package/es/components/wysiwyg/src/extensions/insert.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/lists.d.ts +9 -0
- package/es/components/wysiwyg/src/extensions/lists.js +88 -0
- package/es/components/wysiwyg/src/extensions/lists.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/popover-utils.d.ts +26 -0
- package/es/components/wysiwyg/src/extensions/popover-utils.js +68 -0
- package/es/components/wysiwyg/src/extensions/popover-utils.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/search.d.ts +10 -0
- package/es/components/wysiwyg/src/extensions/search.js +238 -0
- package/es/components/wysiwyg/src/extensions/search.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/tables.d.ts +12 -0
- package/es/components/wysiwyg/src/extensions/tables.js +120 -0
- package/es/components/wysiwyg/src/extensions/tables.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/text-color.d.ts +13 -0
- package/es/components/wysiwyg/src/extensions/text-color.js +159 -0
- package/es/components/wysiwyg/src/extensions/text-color.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/text-formatting.d.ts +9 -0
- package/es/components/wysiwyg/src/extensions/text-formatting.js +93 -0
- package/es/components/wysiwyg/src/extensions/text-formatting.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/typeface.d.ts +9 -0
- package/es/components/wysiwyg/src/extensions/typeface.js +79 -0
- package/es/components/wysiwyg/src/extensions/typeface.js.map +1 -0
- package/es/components/wysiwyg/src/extensions/typography.d.ts +9 -0
- package/es/components/wysiwyg/src/extensions/typography.js +88 -0
- package/es/components/wysiwyg/src/extensions/typography.js.map +1 -0
- package/es/components/wysiwyg/src/roving-tabindex.d.ts +24 -0
- package/es/components/wysiwyg/src/roving-tabindex.js +148 -0
- package/es/components/wysiwyg/src/roving-tabindex.js.map +1 -0
- package/es/components/wysiwyg/src/types.d.ts +57 -0
- package/es/components/wysiwyg/src/types.js +18 -0
- package/es/components/wysiwyg/src/types.js.map +1 -0
- package/es/components/wysiwyg/src/wysiwyg.scss.js +6 -0
- package/es/components/wysiwyg/src/wysiwyg.scss.js.map +1 -0
- package/es/components/wysiwyg/src/wysiwyg.template.d.ts +38 -0
- package/es/components/wysiwyg/src/wysiwyg.template.js +116 -0
- package/es/components/wysiwyg/src/wysiwyg.template.js.map +1 -0
- package/es/components/wysiwyg/wysiwyg.d.ts +20 -0
- package/es/components/wysiwyg/wysiwyg.js +26 -0
- package/es/components/wysiwyg/wysiwyg.js.map +1 -0
- package/es/index.d.ts +22 -0
- package/es/index.js +16 -0
- package/es/index.js.map +1 -0
- package/lib/components/wysiwyg/src/constants.d.ts +9 -0
- package/lib/components/wysiwyg/src/constants.js +19 -0
- package/lib/components/wysiwyg/src/constants.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/alignment.d.ts +16 -0
- package/lib/components/wysiwyg/src/extensions/alignment.js +99 -0
- package/lib/components/wysiwyg/src/extensions/alignment.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/blocks.d.ts +13 -0
- package/lib/components/wysiwyg/src/extensions/blocks.js +94 -0
- package/lib/components/wysiwyg/src/extensions/blocks.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/button-helper.d.ts +62 -0
- package/lib/components/wysiwyg/src/extensions/button-helper.js +73 -0
- package/lib/components/wysiwyg/src/extensions/button-helper.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/clipboard.d.ts +9 -0
- package/lib/components/wysiwyg/src/extensions/clipboard.js +61 -0
- package/lib/components/wysiwyg/src/extensions/clipboard.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/history.d.ts +9 -0
- package/lib/components/wysiwyg/src/extensions/history.js +58 -0
- package/lib/components/wysiwyg/src/extensions/history.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/insert.d.ts +13 -0
- package/lib/components/wysiwyg/src/extensions/insert.js +303 -0
- package/lib/components/wysiwyg/src/extensions/insert.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/lists.d.ts +9 -0
- package/lib/components/wysiwyg/src/extensions/lists.js +90 -0
- package/lib/components/wysiwyg/src/extensions/lists.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/popover-utils.d.ts +26 -0
- package/lib/components/wysiwyg/src/extensions/popover-utils.js +72 -0
- package/lib/components/wysiwyg/src/extensions/popover-utils.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/search.d.ts +10 -0
- package/lib/components/wysiwyg/src/extensions/search.js +240 -0
- package/lib/components/wysiwyg/src/extensions/search.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/tables.d.ts +12 -0
- package/lib/components/wysiwyg/src/extensions/tables.js +122 -0
- package/lib/components/wysiwyg/src/extensions/tables.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/text-color.d.ts +13 -0
- package/lib/components/wysiwyg/src/extensions/text-color.js +161 -0
- package/lib/components/wysiwyg/src/extensions/text-color.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/text-formatting.d.ts +9 -0
- package/lib/components/wysiwyg/src/extensions/text-formatting.js +95 -0
- package/lib/components/wysiwyg/src/extensions/text-formatting.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/typeface.d.ts +9 -0
- package/lib/components/wysiwyg/src/extensions/typeface.js +81 -0
- package/lib/components/wysiwyg/src/extensions/typeface.js.map +1 -0
- package/lib/components/wysiwyg/src/extensions/typography.d.ts +9 -0
- package/lib/components/wysiwyg/src/extensions/typography.js +90 -0
- package/lib/components/wysiwyg/src/extensions/typography.js.map +1 -0
- package/lib/components/wysiwyg/src/roving-tabindex.d.ts +24 -0
- package/lib/components/wysiwyg/src/roving-tabindex.js +148 -0
- package/lib/components/wysiwyg/src/roving-tabindex.js.map +1 -0
- package/lib/components/wysiwyg/src/types.d.ts +57 -0
- package/lib/components/wysiwyg/src/types.js +20 -0
- package/lib/components/wysiwyg/src/types.js.map +1 -0
- package/lib/components/wysiwyg/src/wysiwyg.scss.js +10 -0
- package/lib/components/wysiwyg/src/wysiwyg.scss.js.map +1 -0
- package/lib/components/wysiwyg/src/wysiwyg.template.d.ts +38 -0
- package/lib/components/wysiwyg/src/wysiwyg.template.js +120 -0
- package/lib/components/wysiwyg/src/wysiwyg.template.js.map +1 -0
- package/lib/components/wysiwyg/wysiwyg.d.ts +20 -0
- package/lib/components/wysiwyg/wysiwyg.js +30 -0
- package/lib/components/wysiwyg/wysiwyg.js.map +1 -0
- package/lib/index.d.ts +22 -0
- package/lib/index.js +38 -0
- package/lib/index.js.map +1 -0
- 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;
|