CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tiptap--extension-color

Tiptap extension for applying text colors in rich text editors

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

@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>
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@tiptap/extension-color@3.4.x
Publish Source
CLI
Badge
tessl/npm-tiptap--extension-color badge