or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-tiptap--extension-color

Tiptap extension for applying text colors in rich text editors

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@tiptap/extension-color@3.4.x

To install, run

npx @tessl/cli install tessl/npm-tiptap--extension-color@3.4.0

index.mddocs/

@tiptap/extension-color

@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.

Package Information

  • Package Name: @tiptap/extension-color
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @tiptap/extension-color
  • Dependencies: @tiptap/extension-text-style (workspace dependency), @tiptap/core (peer dependency)

Core Imports

import { Color } from "@tiptap/extension-color";

For default import:

import Color from "@tiptap/extension-color";

With options type (note: ColorOptions is re-exported from @tiptap/extension-text-style):

import { Color, ColorOptions } from "@tiptap/extension-color";

For CommonJS:

const { Color } = require("@tiptap/extension-color");
// or
const Color = require("@tiptap/extension-color").default;

Basic Usage

import { Editor } from "@tiptap/core";
import Document from "@tiptap/extension-document";
import Paragraph from "@tiptap/extension-paragraph";
import Text from "@tiptap/extension-text";
import { TextStyle } from "@tiptap/extension-text-style";
import { Color } from "@tiptap/extension-color";

// Create editor with Color extension
const editor = new Editor({
  extensions: [
    Document,
    Paragraph,
    Text,
    TextStyle, // Required dependency
    Color,     // Color extension
  ],
  content: '<p>Hello <span style="color: #958DF1">colored</span> world!</p>',
});

// Set text color
editor.commands.setColor("#FF0000");           // Hex color
editor.commands.setColor("rgba(255, 0, 0, 0.5)"); // RGBA color
editor.commands.setColor("red");               // Named color

// Remove text color
editor.commands.unsetColor();

// Check if text has specific color
const isPurple = editor.isActive("textStyle", { color: "#958DF1" });

// Get current color
const currentColor = editor.getAttributes("textStyle").color;

Architecture

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:

  • Extension Configuration: Configurable node types where color can be applied
  • Global Attributes: Adds color attribute to specified node types with HTML parsing/rendering
  • Commands: Provides setColor and unsetColor commands for the editor
  • Type Augmentation: Extends Tiptap's command interface and TextStyle attributes

Capabilities

Extension Configuration

Configure which node types can have color applied.

interface ColorOptions {
  /**
   * The types where the color can be applied
   * @default ['textStyle']
   * @example ['heading', 'paragraph']
   */
  types: string[];
}

const Color: Extension<ColorOptions>;

Usage Examples:

// Default configuration (textStyle only)
Color

// Custom configuration for specific node types
Color.configure({
  types: ['heading', 'paragraph', 'textStyle']
})

Color Commands

Apply and remove text colors using editor commands.

interface Commands<ReturnType> {
  color: {
    /**
     * Set the text color
     * @param color The color to set (hex, rgb, rgba, or named CSS color)
     * @example editor.commands.setColor('red')
     * @example editor.commands.setColor('#FF0000')
     * @example editor.commands.setColor('rgba(255, 0, 0, 0.5)')
     */
    setColor: (color: string) => ReturnType;

    /**
     * Unset the text color
     * @example editor.commands.unsetColor()
     */
    unsetColor: () => ReturnType;
  };
}

Usage Examples:

// Chainable command usage
editor.chain().focus().setColor("#958DF1").run();
editor.chain().focus().unsetColor().run();

// Direct command usage
editor.commands.setColor("red");
editor.commands.unsetColor();

// Multiple color formats supported
editor.commands.setColor("#FF0000");                    // Hex
editor.commands.setColor("rgb(255, 0, 0)");            // RGB
editor.commands.setColor("rgba(255, 0, 0, 0.5)");      // RGBA with transparency
editor.commands.setColor("hsl(0, 100%, 50%)");         // HSL
editor.commands.setColor("red");                        // Named CSS colors

Color State Detection

Check active color states and retrieve current color values.

/**
 * Check if text has specific color applied
 * @param mark The mark name (always 'textStyle' for color)
 * @param attributes Object with color property to check
 * @returns boolean indicating if the color is active
 */
editor.isActive(mark: 'textStyle', attributes: { color: string }): boolean;

/**
 * Get current text style attributes including color
 * @param mark The mark name (always 'textStyle' for color)
 * @returns Object containing current attributes including color
 */
editor.getAttributes(mark: 'textStyle'): { color?: string | null };

Usage Examples:

// Check if specific color is active
const isPurple = editor.isActive('textStyle', { color: '#958DF1' });
const isRed = editor.isActive('textStyle', { color: 'red' });

// Get current color
const attributes = editor.getAttributes('textStyle');
const currentColor = attributes.color; // string | null | undefined

// Conditional styling based on active color
if (editor.isActive('textStyle', { color: '#958DF1' })) {
  // Style UI button as active for purple color
}

HTML Integration

The extension automatically handles HTML parsing and rendering of colored text.

HTML Output:

<!-- Extension generates inline styles -->
<span style="color: #958DF1">Purple text</span>
<span style="color: rgba(255, 0, 0, 0.5)">Transparent red text</span>

HTML Parsing:

  • Prefers raw style attribute over computed styles to preserve original format
  • Handles nested spans with multiple color declarations by using the last (innermost) declaration
  • Strips quotes from color values during parsing
  • Supports both inline styles and computed CSS color values

Types

/**
 * Configuration options for the Color extension
 * Note: This type is re-exported from @tiptap/extension-text-style
 */
interface ColorOptions {
  /**
   * Array of node type names where color can be applied
   * @default ['textStyle']
   */
  types: string[];
}

/**
 * Extended TextStyle attributes to include color
 * Note: This interface is augmented in @tiptap/extension-text-style
 */
interface TextStyleAttributes {
  /**
   * CSS color value or null if no color is set
   */
  color?: string | null;
}

/**
 * The Color extension instance
 * Note: This is re-exported from @tiptap/extension-text-style
 */
const Color: Extension<ColorOptions>;

/**
 * Default export - the Color extension instance
 */
export default Color;

Error Handling

The Color extension handles common edge cases gracefully:

  • Invalid Colors: Invalid CSS color values are ignored during HTML parsing
  • Missing TextStyle: Extension requires TextStyle extension to be loaded
  • Nested Color Declarations: When parsing HTML with nested color styles, the innermost color takes precedence
  • Quote Handling: Automatically strips single and double quotes from color values

Integration Patterns

React Integration

import { useEditor, EditorContent } from "@tiptap/react";
import { Color } from "@tiptap/extension-color";
import { TextStyle } from "@tiptap/extension-text-style";

function ColorEditor() {
  const editor = useEditor({
    extensions: [Document, Paragraph, Text, TextStyle, Color],
    content: "<p>Hello world!</p>",
  });

  return (
    <div>
      <input
        type="color"
        onChange={(e) => editor?.commands.setColor(e.target.value)}
        value={editor?.getAttributes("textStyle").color || "#000000"}
      />
      <button onClick={() => editor?.commands.unsetColor()}>
        Remove Color
      </button>
      <EditorContent editor={editor} />
    </div>
  );
}

Vue Integration

<template>
  <div>
    <input
      type="color"
      @input="editor.commands.setColor($event.target.value)"
      :value="editor.getAttributes('textStyle').color || '#000000'"
    />
    <button @click="editor.commands.unsetColor()">Remove Color</button>
    <editor-content :editor="editor" />
  </div>
</template>

<script>
import { Editor, EditorContent } from "@tiptap/vue-3";
import { Color } from "@tiptap/extension-color";
import { TextStyle } from "@tiptap/extension-text-style";

export default {
  components: { EditorContent },
  data() {
    return {
      editor: new Editor({
        extensions: [Document, Paragraph, Text, TextStyle, Color],
        content: "<p>Hello world!</p>",
      }),
    };
  },
};
</script>