0
# @tiptap/extension-color
1
2
@tiptap/extension-color is a text color extension for Tiptap, a headless rich text editor built on ProseMirror. This extension enables users to apply custom text colors to any text selection within Tiptap editor instances, with support for hex colors, RGB/RGBA values, and named CSS colors.
3
4
## Package Information
5
6
- **Package Name**: @tiptap/extension-color
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @tiptap/extension-color`
10
- **Dependencies**: `@tiptap/extension-text-style` (workspace dependency), `@tiptap/core` (peer dependency)
11
12
## Core Imports
13
14
```typescript
15
import { Color } from "@tiptap/extension-color";
16
```
17
18
For default import:
19
20
```typescript
21
import Color from "@tiptap/extension-color";
22
```
23
24
With options type (note: ColorOptions is re-exported from @tiptap/extension-text-style):
25
26
```typescript
27
import { Color, ColorOptions } from "@tiptap/extension-color";
28
```
29
30
For CommonJS:
31
32
```javascript
33
const { Color } = require("@tiptap/extension-color");
34
// or
35
const Color = require("@tiptap/extension-color").default;
36
```
37
38
## Basic Usage
39
40
```typescript
41
import { Editor } from "@tiptap/core";
42
import Document from "@tiptap/extension-document";
43
import Paragraph from "@tiptap/extension-paragraph";
44
import Text from "@tiptap/extension-text";
45
import { TextStyle } from "@tiptap/extension-text-style";
46
import { Color } from "@tiptap/extension-color";
47
48
// Create editor with Color extension
49
const editor = new Editor({
50
extensions: [
51
Document,
52
Paragraph,
53
Text,
54
TextStyle, // Required dependency
55
Color, // Color extension
56
],
57
content: '<p>Hello <span style="color: #958DF1">colored</span> world!</p>',
58
});
59
60
// Set text color
61
editor.commands.setColor("#FF0000"); // Hex color
62
editor.commands.setColor("rgba(255, 0, 0, 0.5)"); // RGBA color
63
editor.commands.setColor("red"); // Named color
64
65
// Remove text color
66
editor.commands.unsetColor();
67
68
// Check if text has specific color
69
const isPurple = editor.isActive("textStyle", { color: "#958DF1" });
70
71
// Get current color
72
const currentColor = editor.getAttributes("textStyle").color;
73
```
74
75
## Architecture
76
77
The Color extension is built on Tiptap's extension system and relies on the TextStyle extension for mark-based styling. **Note**: `@tiptap/extension-color` is a thin wrapper package that re-exports the Color extension from `@tiptap/extension-text-style`. Key components include:
78
79
- **Extension Configuration**: Configurable node types where color can be applied
80
- **Global Attributes**: Adds `color` attribute to specified node types with HTML parsing/rendering
81
- **Commands**: Provides `setColor` and `unsetColor` commands for the editor
82
- **Type Augmentation**: Extends Tiptap's command interface and TextStyle attributes
83
84
## Capabilities
85
86
### Extension Configuration
87
88
Configure which node types can have color applied.
89
90
```typescript { .api }
91
interface ColorOptions {
92
/**
93
* The types where the color can be applied
94
* @default ['textStyle']
95
* @example ['heading', 'paragraph']
96
*/
97
types: string[];
98
}
99
100
const Color: Extension<ColorOptions>;
101
```
102
103
**Usage Examples:**
104
105
```typescript
106
// Default configuration (textStyle only)
107
Color
108
109
// Custom configuration for specific node types
110
Color.configure({
111
types: ['heading', 'paragraph', 'textStyle']
112
})
113
```
114
115
### Color Commands
116
117
Apply and remove text colors using editor commands.
118
119
```typescript { .api }
120
interface Commands<ReturnType> {
121
color: {
122
/**
123
* Set the text color
124
* @param color The color to set (hex, rgb, rgba, or named CSS color)
125
* @example editor.commands.setColor('red')
126
* @example editor.commands.setColor('#FF0000')
127
* @example editor.commands.setColor('rgba(255, 0, 0, 0.5)')
128
*/
129
setColor: (color: string) => ReturnType;
130
131
/**
132
* Unset the text color
133
* @example editor.commands.unsetColor()
134
*/
135
unsetColor: () => ReturnType;
136
};
137
}
138
```
139
140
**Usage Examples:**
141
142
```typescript
143
// Chainable command usage
144
editor.chain().focus().setColor("#958DF1").run();
145
editor.chain().focus().unsetColor().run();
146
147
// Direct command usage
148
editor.commands.setColor("red");
149
editor.commands.unsetColor();
150
151
// Multiple color formats supported
152
editor.commands.setColor("#FF0000"); // Hex
153
editor.commands.setColor("rgb(255, 0, 0)"); // RGB
154
editor.commands.setColor("rgba(255, 0, 0, 0.5)"); // RGBA with transparency
155
editor.commands.setColor("hsl(0, 100%, 50%)"); // HSL
156
editor.commands.setColor("red"); // Named CSS colors
157
```
158
159
### Color State Detection
160
161
Check active color states and retrieve current color values.
162
163
```typescript { .api }
164
/**
165
* Check if text has specific color applied
166
* @param mark The mark name (always 'textStyle' for color)
167
* @param attributes Object with color property to check
168
* @returns boolean indicating if the color is active
169
*/
170
editor.isActive(mark: 'textStyle', attributes: { color: string }): boolean;
171
172
/**
173
* Get current text style attributes including color
174
* @param mark The mark name (always 'textStyle' for color)
175
* @returns Object containing current attributes including color
176
*/
177
editor.getAttributes(mark: 'textStyle'): { color?: string | null };
178
```
179
180
**Usage Examples:**
181
182
```typescript
183
// Check if specific color is active
184
const isPurple = editor.isActive('textStyle', { color: '#958DF1' });
185
const isRed = editor.isActive('textStyle', { color: 'red' });
186
187
// Get current color
188
const attributes = editor.getAttributes('textStyle');
189
const currentColor = attributes.color; // string | null | undefined
190
191
// Conditional styling based on active color
192
if (editor.isActive('textStyle', { color: '#958DF1' })) {
193
// Style UI button as active for purple color
194
}
195
```
196
197
### HTML Integration
198
199
The extension automatically handles HTML parsing and rendering of colored text.
200
201
**HTML Output:**
202
```html
203
<!-- Extension generates inline styles -->
204
<span style="color: #958DF1">Purple text</span>
205
<span style="color: rgba(255, 0, 0, 0.5)">Transparent red text</span>
206
```
207
208
**HTML Parsing:**
209
- Prefers raw `style` attribute over computed styles to preserve original format
210
- Handles nested spans with multiple color declarations by using the last (innermost) declaration
211
- Strips quotes from color values during parsing
212
- Supports both inline styles and computed CSS color values
213
214
## Types
215
216
```typescript { .api }
217
/**
218
* Configuration options for the Color extension
219
* Note: This type is re-exported from @tiptap/extension-text-style
220
*/
221
interface ColorOptions {
222
/**
223
* Array of node type names where color can be applied
224
* @default ['textStyle']
225
*/
226
types: string[];
227
}
228
229
/**
230
* Extended TextStyle attributes to include color
231
* Note: This interface is augmented in @tiptap/extension-text-style
232
*/
233
interface TextStyleAttributes {
234
/**
235
* CSS color value or null if no color is set
236
*/
237
color?: string | null;
238
}
239
240
/**
241
* The Color extension instance
242
* Note: This is re-exported from @tiptap/extension-text-style
243
*/
244
const Color: Extension<ColorOptions>;
245
246
/**
247
* Default export - the Color extension instance
248
*/
249
export default Color;
250
```
251
252
## Error Handling
253
254
The Color extension handles common edge cases gracefully:
255
256
- **Invalid Colors**: Invalid CSS color values are ignored during HTML parsing
257
- **Missing TextStyle**: Extension requires TextStyle extension to be loaded
258
- **Nested Color Declarations**: When parsing HTML with nested color styles, the innermost color takes precedence
259
- **Quote Handling**: Automatically strips single and double quotes from color values
260
261
## Integration Patterns
262
263
### React Integration
264
265
```typescript
266
import { useEditor, EditorContent } from "@tiptap/react";
267
import { Color } from "@tiptap/extension-color";
268
import { TextStyle } from "@tiptap/extension-text-style";
269
270
function ColorEditor() {
271
const editor = useEditor({
272
extensions: [Document, Paragraph, Text, TextStyle, Color],
273
content: "<p>Hello world!</p>",
274
});
275
276
return (
277
<div>
278
<input
279
type="color"
280
onChange={(e) => editor?.commands.setColor(e.target.value)}
281
value={editor?.getAttributes("textStyle").color || "#000000"}
282
/>
283
<button onClick={() => editor?.commands.unsetColor()}>
284
Remove Color
285
</button>
286
<EditorContent editor={editor} />
287
</div>
288
);
289
}
290
```
291
292
### Vue Integration
293
294
```vue
295
<template>
296
<div>
297
<input
298
type="color"
299
@input="editor.commands.setColor($event.target.value)"
300
:value="editor.getAttributes('textStyle').color || '#000000'"
301
/>
302
<button @click="editor.commands.unsetColor()">Remove Color</button>
303
<editor-content :editor="editor" />
304
</div>
305
</template>
306
307
<script>
308
import { Editor, EditorContent } from "@tiptap/vue-3";
309
import { Color } from "@tiptap/extension-color";
310
import { TextStyle } from "@tiptap/extension-text-style";
311
312
export default {
313
components: { EditorContent },
314
data() {
315
return {
316
editor: new Editor({
317
extensions: [Document, Paragraph, Text, TextStyle, Color],
318
content: "<p>Hello world!</p>",
319
}),
320
};
321
},
322
};
323
</script>
324
```