Block Color
BlockColor adds block-level background and text colors as global attributes. The colors persist across turnIntoBlock transformations (the heading-to-paragraph swap keeps its tint), and integrate with BlockContextMenu’s Colors picker so the user can apply colors via the right-click menu.
This complements NotionColorPicker, which handles inline color (per-character tints via textStyle). Use BlockColor for whole-block tints (e.g. an entire paragraph or list item highlighted).
Not included in StarterKit.
Quickstart
Section titled “Quickstart”import { Editor, StarterKit, BlockColor } from '@domternal/core';import '@domternal/theme';
const editor = new Editor({ element: document.getElementById('editor')!, extensions: [ StarterKit, BlockColor, ],});
// Apply a background color to the block at the cursoreditor.chain().focus().setBlockBgColor('blue').run();Options
Section titled “Options”BlockColor.configure({ types: DEFAULT_BLOCK_COLOR_TYPES, bgColors: DEFAULT_BLOCK_COLORS, textColors: DEFAULT_BLOCK_COLORS,})| Option | Type | Default | Description |
|---|---|---|---|
types | string[] | DEFAULT_BLOCK_COLOR_TYPES | Node types that receive bgColor / textColor global attributes |
bgColors | string[] | DEFAULT_BLOCK_COLORS | Palette used by setBlockBgColor. Commands reject values outside this list (no-op + returns false) so host apps can curate what’s selectable. |
textColors | string[] | DEFAULT_BLOCK_COLORS | Palette used by setBlockTextColor |
DEFAULT_BLOCK_COLOR_TYPES
Section titled “DEFAULT_BLOCK_COLOR_TYPES”['paragraph', 'heading', 'blockquote', 'bulletList', 'orderedList', 'taskList', 'listItem', 'taskItem']codeBlock is intentionally excluded - <pre><code> already has its own background that would clash visually. Details-content blocks similarly have their own affordance.
DEFAULT_BLOCK_COLORS
Section titled “DEFAULT_BLOCK_COLORS”['gray', 'brown', 'orange', 'yellow', 'green', 'blue', 'purple', 'pink', 'red']Same 9-color palette as NotionColorPicker, so inline and block tints share the same color set. 'default' is implicit - represented by null (no data-* attribute).
Schema attributes
Section titled “Schema attributes”The extension adds two global attributes (parse/render on every type in types):
| Attribute | Parses | Renders | Meaning |
|---|---|---|---|
bgColor | data-bg-color="<token>" | data-bg-color="<token>" | Block background color |
textColor | data-text-color="<token>" | data-text-color="<token>" | Block text color |
The theme stylesheet maps these data attributes to CSS custom properties:
[data-bg-color="blue"] { background-color: var(--dm-block-bg-blue); }[data-text-color="red"] { color: var(--dm-block-text-red); }Commands
Section titled “Commands”declare module '@domternal/core' { interface RawCommands { setBlockBgColor: CommandSpec<[color: string | null]>; setBlockTextColor: CommandSpec<[color: string | null]>; unsetBlockColors: CommandSpec; }}| Command | Signature | Behavior |
|---|---|---|
setBlockBgColor | (color: string | null) | Sets bgColor on every block in the selection range that has a type in types. null clears. Rejects values outside bgColors palette (returns false). |
setBlockTextColor | (color: string | null) | Same for textColor, rejects values outside textColors palette |
unsetBlockColors | () | Clears both bgColor and textColor on every block in the selection range |
editor.chain().focus().setBlockBgColor('green').run(); // seteditor.chain().focus().setBlockTextColor(null).run(); // cleareditor.chain().focus().unsetBlockColors().run(); // clear botheditor.chain().focus().setBlockBgColor('notacolor').run(); // false - palette guard rejectsturnIntoBlock persistence
Section titled “turnIntoBlock persistence”When the user changes a block’s type via “Turn into” (e.g. heading -> paragraph), BlockContextMenu’s turnIntoBlock helper transforms attrs through a custom function so global attrs survive. Without this preservation, every block-type change would silently reset the color.
// User has: <p data-bg-color="blue">text</p>// User clicks "Turn into > Heading 1"// Result: <h1 data-bg-color="blue">text</h1> <-- color persistsConflict resolution: stripInlineColorConflicts
Section titled “Conflict resolution: stripInlineColorConflicts”The extension exports a utility used by BlockContextMenu to ensure that applying a block color removes conflicting inline colors so the new block tint isn’t visually masked:
import { stripInlineColorConflicts } from '@domternal/core';
function stripInlineColorConflicts( tr: Transaction, state: EditorState, from: number, to: number, which: 'text' | 'bg' | 'both',): void;Strips inline textStyle marks inside [from, to] that carry the inline counterpart of a block-level color attribute. Mutates the transaction in place. 'both' handles the unset case (unsetBlockColors).
Integration with BlockContextMenu
Section titled “Integration with BlockContextMenu”When both BlockColor and BlockContextMenu are loaded, the context menu’s Colors section appears automatically for blocks of types in BlockColor.options.types. The Colors row shows two ribbons (background + text) with the full palette plus a “default” swatch (clear).
Toggle off via BlockContextMenu.configure({ blockColorEnabled: false }).
CSS classes
Section titled “CSS classes”Block colors render only as data attributes; the theme stylesheet picks them up via attribute selectors. No new classes are added directly by this extension.
CSS theme tokens
Section titled “CSS theme tokens”Defined in @domternal/theme for both light and dark modes:
| Variable | Purpose |
|---|---|
--dm-block-bg-gray | Background for data-bg-color="gray" |
--dm-block-bg-brown | Background for data-bg-color="brown" |
--dm-block-bg-orange etc. | Backgrounds for each palette token |
--dm-block-text-gray | Text color for data-text-color="gray" |
--dm-block-text-brown etc. | Text colors for each palette token |
Override these in your app’s CSS to customize the palette colors.
Exports
Section titled “Exports”import { BlockColor, DEFAULT_BLOCK_COLORS, DEFAULT_BLOCK_COLOR_TYPES, stripInlineColorConflicts,} from '@domternal/core';import type { BlockColorOptions } from '@domternal/core';Source
Section titled “Source”@domternal/core - BlockColor.ts