blokhaus

ColorPicker

Text and highlight color picker component.

ColorPicker renders a compact color selection panel with two sections: text color and background highlight color. It is primarily used inside the FloatingToolbar but can also be used standalone within a Lexical editor context.

Import

import { ColorPicker } from "@blokhaus/core";
import type { ColorPalette, ColorEntry } from "@blokhaus/core";

Props

PropTypeDefaultDescription
paletteColorPaletteDEFAULT_COLOR_PALETTEColor palette configuration with text and highlight color arrays.
activeTextColorstring | nullrequiredThe currently active text color CSS value, or null if using the default color.
activeHighlightColorstring | nullrequiredThe currently active highlight/background color CSS value, or null if using the default.
onClose() => voidrequiredCallback invoked after a color is selected. Typically used to close the picker dropdown.

Basic usage

The ColorPicker is typically used inside the FloatingToolbar and does not need to be added separately. However, you can use it in a custom toolbar or UI:

"use client";

import { useState } from "react";
import { ColorPicker } from "@blokhaus/core";

function CustomColorControl() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div style={{ position: "relative" }}>
      <button onClick={() => setIsOpen(!isOpen)}>Colors</button>

      {isOpen && (
        <div style={{ position: "absolute", top: "100%", zIndex: 50 }}>
          <ColorPicker
            activeTextColor={null}
            activeHighlightColor={null}
            onClose={() => setIsOpen(false)}
          />
        </div>
      )}
    </div>
  );
}

Color palette structure

The ColorPalette type contains two arrays of ColorEntry objects:

interface ColorEntry {
  /** Human-readable label shown in the picker */
  label: string;
  /** CSS value to apply -- should be a var() reference */
  value: string;
  /** Preview swatch color (raw hex/hsl for rendering the dot in the picker) */
  swatch: string;
}

interface ColorPalette {
  text: ColorEntry[];
  highlight: ColorEntry[];
}

Default color palette

The default palette includes 10 text colors and 10 highlight colors:

Text colors

ColorCSS VariableSwatch
Default(removes color)currentColor
Grayvar(--blokhaus-text-gray)#9b9a97
Brownvar(--blokhaus-text-brown)#64473a
Orangevar(--blokhaus-text-orange)#d9730d
Yellowvar(--blokhaus-text-yellow)#dfab01
Greenvar(--blokhaus-text-green)#0f7b6c
Bluevar(--blokhaus-text-blue)#0b6e99
Purplevar(--blokhaus-text-purple)#6940a5
Pinkvar(--blokhaus-text-pink)#ad1a72
Redvar(--blokhaus-text-red)#e03e3e

Highlight colors

ColorCSS VariableSwatch
Default(removes highlight)transparent
Grayvar(--blokhaus-highlight-gray)#ebeced
Brownvar(--blokhaus-highlight-brown)#e9e5e3
Orangevar(--blokhaus-highlight-orange)#faebdd
Yellowvar(--blokhaus-highlight-yellow)#fbf3db
Greenvar(--blokhaus-highlight-green)#ddedea
Bluevar(--blokhaus-highlight-blue)#ddebf1
Purplevar(--blokhaus-highlight-purple)#eae4f2
Pinkvar(--blokhaus-highlight-pink)#f4dfeb
Redvar(--blokhaus-highlight-red)#fbe4e4

Custom palette

Override the default palette by passing a custom ColorPalette:

import type { ColorPalette } from "@blokhaus/core";

const brandPalette: ColorPalette = {
  text: [
    { label: "Default", value: "", swatch: "currentColor" },
    { label: "Primary", value: "var(--brand-primary)", swatch: "#6366f1" },
    { label: "Secondary", value: "var(--brand-secondary)", swatch: "#8b5cf6" },
    { label: "Danger", value: "var(--brand-danger)", swatch: "#ef4444" },
  ],
  highlight: [
    { label: "Default", value: "", swatch: "transparent" },
    { label: "Highlight", value: "var(--brand-highlight)", swatch: "#fef08a" },
    { label: "Success", value: "var(--brand-success-bg)", swatch: "#dcfce7" },
  ],
};

<ColorPicker
  palette={brandPalette}
  activeTextColor={null}
  activeHighlightColor={null}
  onClose={() => {}}
/>;

Commands dispatched

When a color is selected, the ColorPicker dispatches Lexical commands:

  • Text color: SET_TEXT_COLOR_COMMAND with the CSS value string
  • Highlight color: SET_HIGHLIGHT_COLOR_COMMAND with the CSS value string

An empty string value ("") removes the color, reverting to the default.

After dispatching the command, the picker calls editor.focus() to return focus to the editor and then invokes the onClose callback.

Visual indicators

  • The active text color is indicated by a small checkmark icon in the bottom-right corner of the swatch button.
  • The active highlight color is indicated by a centered checkmark icon.
  • The "Default" text color swatch renders an "A" character in the current foreground color.
  • The "Default" highlight swatch is transparent and displays a null symbol.

Notes

  • ColorPicker is a client component ('use client').
  • It must be rendered within a LexicalComposer context (i.e., inside EditorRoot).
  • The component uses onMouseDown with e.preventDefault() to prevent the editor from losing focus when clicking color swatches.
  • Color values use CSS variable references (e.g., var(--blokhaus-text-red)) so that colors can be customized via the theme's tokens.css without modifying the picker.