Skip to content

Highlight

Highlight adds background color highlighting via the TextStyle carrier mark. It provides a 25-color palette, setHighlight, unsetHighlight, and toggleHighlight commands, a Mod-Shift-H keyboard shortcut, an ==text== input rule, and a toolbar dropdown with color swatches. When the color list is empty, it falls back to a simple toggle button.

Not included in StarterKit. Add it separately.

Requires the TextStyle mark. If you are not already using TextColor, FontFamily, or FontSize (which auto-include TextStyle), you need to add it manually.

Select some text and pick a highlight color from the palette dropdown. You can also type ==text== or press Cmd/Ctrl+Shift+H to toggle the default highlight color.

With the default theme. The toolbar shows a highlight palette dropdown with 25 color swatches and a reset button.

Click to try it out
import { Editor, Document, Paragraph, Text, TextStyle, Highlight } from '@domternal/core';
import '@domternal/theme';
const editor = new Editor({
element: document.getElementById('editor')!,
extensions: [Document, Paragraph, Text, TextStyle, Highlight],
content: '<p>Select text and pick a highlight color from the toolbar.</p>',
});

With the full theme and ToolbarController, Highlight renders as a dropdown with a 5x5 color palette grid and a “No highlight” reset button.

OptionTypeDefaultDescription
colorsstring[]DEFAULT_HIGHLIGHT_COLORS (25 colors)Color values for the palette. Pass an empty array for a simple toggle button.
columnsnumber5Number of columns in the palette grid layout
defaultColorstring#fef08aDefault highlight color used by the keyboard shortcut and ==text== input rule
Highlight.configure({
colors: ['#fef08a', '#a7f3d0', '#bfdbfe', '#c4b5fd', '#fecaca'],
columns: 5,
defaultColor: '#fef08a',
})

The default palette is a 5x5 grid organized by color temperature and intensity:

RowDescriptionColors
1Classic warm highlights#fef08a #fde68a #fed7aa #fecaca #fbcfe8
2Lighter warm pastels#fef9c3 #fef3c7 #ffedd5 #fee2e2 #fce7f3
3Cool highlights#a7f3d0 #99f6e4 #a5f3fc #bfdbfe #c4b5fd
4Lighter cool pastels#d1fae5 #ccfbf1 #cffafe #dbeafe #ede9fe
5Neutrals#e5e7eb #d1d5db #f3f4f6 #fafafa #ffffff

You can import the default palette to extend it:

import { Highlight, DEFAULT_HIGHLIGHT_COLORS } from '@domternal/core';
Highlight.configure({
colors: [...DEFAULT_HIGHLIGHT_COLORS, '#ff69b4'],
})

Passing an empty colors array replaces the dropdown with a simple toggle button that uses the defaultColor:

Highlight.configure({ colors: [] }) // toggle button, no palette

The button uses toggleHighlight and shows as active when the default color is applied.

Sets the background color on the current selection. Uses defaultColor if no color is provided.

editor.commands.setHighlight(); // uses defaultColor (#fef08a)
editor.commands.setHighlight({ color: '#a7f3d0' }); // specific color
// With chaining
editor.chain().focus().setHighlight({ color: '#bfdbfe' }).run();

Removes the background color from the current selection. Also cleans up empty <span> wrappers via removeEmptyTextStyle().

editor.commands.unsetHighlight();

Toggles the background color on the current selection. If highlighted, removes it. If not highlighted, applies the color.

editor.commands.toggleHighlight(); // toggle with defaultColor
editor.commands.toggleHighlight({ color: '#c4b5fd' }); // toggle specific color

The toggle checks both empty selections (stored marks) and non-empty selections (document marks) to determine if a highlight is currently active.

KeyCommandDescription
Mod-Shift-HtoggleHighlight()Toggle highlight with default color

Mod is Cmd on macOS and Ctrl on Windows/Linux.

InputResult
==text==Highlighted text with the defaultColor

The input rule matches == wrapped text at the end of input. It replaces the markers with the text content and applies the backgroundColor attribute via the TextStyle mark. The == delimiters are removed from the output.

Highlight registers either a dropdown with grid layout or a simple button, depending on the colors option.

DropdownIconGroupPriorityLayoutGrid columns
highlighthighlighterCircleformat150grid5 (configurable)

The dropdown contains 26 items: 1 reset button + 25 color swatches.

Reset button:

ItemCommandIconLabel
unsetHighlightunsetHighlightprohibitNo highlight

Color swatches: Each color becomes a swatch button with isActive: { name: 'textStyle', attributes: { backgroundColor: color } }.

ButtonIconGroupPriorityShortcut
highlighthighlighterCircleformat150Mod-Shift-H

A simple toggle button that calls toggleHighlight with the default color.

Highlight injects a backgroundColor attribute into the TextStyle mark using addGlobalAttributes():

addGlobalAttributes() {
return [{
types: ['textStyle'],
attributes: {
backgroundColor: {
default: null,
parseHTML: (element) => {
const raw = element.style.backgroundColor.replace(/['"]+/g, '');
if (raw) return normalizeColor(raw);
if (element.tagName === 'MARK') return options.defaultColor;
return null;
},
renderHTML: (attributes) =>
attributes.backgroundColor
? { style: `background-color: ${attributes.backgroundColor}` }
: null,
},
},
}];
}

This means Highlight, TextColor, FontFamily, and FontSize all share the same <span> wrapper:

<span style="background-color: #fef08a; color: #e03131">highlighted and colored</span>

The TextStyle mark’s parseHTML includes a rule for <mark> elements. When a <mark> tag is parsed without an explicit background-color style, Highlight assigns the defaultColor value. This ensures pasted <mark> content from external sources gets the configured highlight color.

toggleHighlight checks for an active highlight before deciding to set or unset:

  1. For empty selections (collapsed cursor): checks stored marks for a backgroundColor attribute
  2. For non-empty selections: walks document nodes between from and to, checking marks
  3. If any highlight is found, it unsets; otherwise it sets the color

Like TextColor, Highlight uses normalizeColor() to convert browser rgb() values back to hex format. This ensures consistent comparison for active state detection.

When you call unsetHighlight(), it sets backgroundColor to null and calls removeEmptyTextStyle(). If no other TextStyle attributes remain (no color, font-family, font-size), the <span> wrapper is removed entirely.

Highlights render as inline styles on <span> elements, not as <mark> tags:

<!-- With highlight -->
<span style="background-color: #fef08a">Highlighted text</span>
<!-- No highlight - no span wrapper -->
Plain text
import { Highlight, DEFAULT_HIGHLIGHT_COLORS } from '@domternal/core';
import type { HighlightOptions } from '@domternal/core';
ExportTypeDescription
HighlightExtensionThe highlight extension
DEFAULT_HIGHLIGHT_COLORSstring[]The default 25-color palette array
HighlightOptionsTypeScript typeOptions for Highlight.configure()

@domternal/core - Highlight.ts