Skip to main content

Overview

Mark types define text-level formatting in Yoopta Editor. Marks are applied to text nodes within elements to add styling like bold, italic, underline, and custom formatting. This page documents the types used to create and manage marks.

YooptaMark

The main type for defining a mark.
type YooptaMark<TProps> = {
  type: string;
  hotkey?: string;
  render: (props: TProps) => JSX.Element;
};

Properties

type
string
required
Unique identifier for the mark (e.g., "bold", "italic", "highlight"). This should match the property name used in text nodes.
hotkey
string
Keyboard shortcut to toggle the mark. Uses the same format as plugin shortcuts:
  • "mod+b" - Cmd/Ctrl + B
  • "mod+i" - Cmd/Ctrl + I
  • "mod+shift+h" - Cmd/Ctrl + Shift + H
render
function
required
React component to render the mark. Receives props specific to the mark type, including children and mark-specific properties.
render: (props) => {
  return <strong>{props.children}</strong>;
}

YooptaMarkParams

Parameters for creating a mark using createYooptaMark.
type YooptaMarkParams<TProps> = {
  type: string;
  hotkey?: string;
  render: (props: TProps) => JSX.Element;
};
Identical to YooptaMark, used as input to the createYooptaMark function.

SlateElementTextNode

Text node structure with mark properties.
type SlateElementTextNode = {
  text: string;
  bold?: boolean;
  italic?: boolean;
  underline?: boolean;
  code?: boolean;
  strike?: boolean;
  highlight?: any;
};

Properties

text
string
required
The actual text content.
bold
boolean
Bold formatting mark.
italic
boolean
Italic formatting mark.
underline
boolean
Underline formatting mark.
code
boolean
Inline code formatting mark.
strike
boolean
Strikethrough formatting mark.
highlight
any
Highlight mark, typically with color information.
{ color: '#ffff00', backgroundColor: '#ffff00' }

TextFormat

Runtime representation of a mark with active state and methods.
type TextFormat = {
  type: string;
  hotkey?: string;
  getValue: () => null | any;
  isActive: () => boolean;
  toggle: () => void;
  update: (props?: any) => void;
};

Properties

type
string
required
Mark type identifier.
hotkey
string
Keyboard shortcut for the mark.
getValue
function
required
Returns the current value of the mark at the selection, or null if not active.
const value = editor.formats.bold.getValue();
// Returns: true | null
isActive
function
required
Returns true if the mark is active at the current selection.
const isBold = editor.formats.bold.isActive();
toggle
function
required
Toggles the mark on/off at the current selection.
editor.formats.bold.toggle();
update
function
required
Updates the mark with new properties.
editor.formats.highlight.update({
  color: '#ff0000',
  backgroundColor: '#ffff00'
});

YooptaMarkProps

Props passed to mark render functions.
type YooptaMarkProps<K extends string, V> = {
  children: RenderLeafProps['children'];
  leaf: ExtendedLeaf<K, V>;
};

Properties

children
ReactNode
required
The text content to be wrapped by the mark.
leaf
ExtendedLeaf<K, V>
required
The leaf node containing text and all active marks.

ExtendedLeaf

Extended text node with mark properties.
type ExtendedLeaf<K extends string, V> = RenderLeafProps['leaf'] & LeafFormats<K, V> & {
  withPlaceholder?: boolean;
  elementPlaceholder?: string;
};

Creating Marks

Using createYooptaMark

import { createYooptaMark } from '@yoopta/editor';

const BoldMark = createYooptaMark({
  type: 'bold',
  hotkey: 'mod+b',
  render: ({ children }) => <strong>{children}</strong>,
});

const ItalicMark = createYooptaMark({
  type: 'italic',
  hotkey: 'mod+i',
  render: ({ children }) => <em>{children}</em>,
});

const CodeMark = createYooptaMark({
  type: 'code',
  hotkey: 'mod+e',
  render: ({ children }) => <code>{children}</code>,
});

Custom Mark with Properties

type HighlightProps = {
  children: React.ReactNode;
  leaf: {
    text: string;
    highlight?: {
      color?: string;
      backgroundColor?: string;
    };
  };
};

const HighlightMark = createYooptaMark<HighlightProps>({
  type: 'highlight',
  hotkey: 'mod+shift+h',
  render: ({ children, leaf }) => {
    const style = {
      color: leaf.highlight?.color || '#000',
      backgroundColor: leaf.highlight?.backgroundColor || '#ffff00',
    };
    
    return <mark style={style}>{children}</mark>;
  },
});

Using Marks

Registering Marks

import { createYooptaEditor } from '@yoopta/editor';
import { BoldMark, ItalicMark, UnderlineMark } from '@yoopta/marks';

const editor = createYooptaEditor({
  plugins,
  marks: [BoldMark, ItalicMark, UnderlineMark],
});

Accessing Marks at Runtime

// Access through editor.formats
const formats = editor.formats;

// Toggle bold
formats.bold.toggle();

// Check if italic is active
if (formats.italic.isActive()) {
  console.log('Text is italic');
}

// Get highlight value
const highlightValue = formats.highlight.getValue();

Using Marks API

import { Marks } from '@yoopta/editor';

// Update marks for specific blocks
Marks.update(editor, {
  type: 'highlight',
  value: { 
    color: '#000',
    backgroundColor: '#ffff00' 
  },
  at: [0, 1, 2], // Block indices to apply to
});

Creating Text with Marks

// Using editor.y.text
const boldText = editor.y.text('Bold text', { bold: true });
const italicText = editor.y.text('Italic text', { italic: true });
const styledText = editor.y.text('Styled text', {
  bold: true,
  italic: true,
  underline: true,
});

// Create element with marked text
const paragraph = editor.y('paragraph', {
  children: [
    editor.y.text('Normal text '),
    editor.y.text('bold', { bold: true }),
    editor.y.text(' and '),
    editor.y.text('italic', { italic: true }),
  ],
});

Built-in Marks

Yoopta Editor provides standard marks through @yoopta/marks:
import {
  BoldMark,        // Bold text (mod+b)
  ItalicMark,      // Italic text (mod+i)
  UnderlineMark,   // Underlined text (mod+u)
  StrikeMark,      // Strikethrough text (mod+shift+s)
  CodeMark,        // Inline code (mod+e)
  HighlightMark,   // Highlighted text (mod+shift+h)
} from '@yoopta/marks';

Mark Rendering Example

const CustomHighlightMark = createYooptaMark<{
  children: React.ReactNode;
  leaf: {
    text: string;
    highlight?: {
      color?: string;
      backgroundColor?: string;
    };
  };
}>({
  type: 'highlight',
  hotkey: 'mod+shift+h',
  render: ({ children, leaf }) => {
    if (!leaf.highlight) return <>{children}</>;
    
    return (
      <mark
        style={{
          color: leaf.highlight.color,
          backgroundColor: leaf.highlight.backgroundColor,
          padding: '2px 4px',
          borderRadius: '3px',
        }}
      >
        {children}
      </mark>
    );
  },
});

Text Node with Multiple Marks

const textNode: SlateElementTextNode = {
  text: 'Important note',
  bold: true,
  italic: true,
  highlight: {
    color: '#000',
    backgroundColor: '#ffff00',
  },
};

// When rendered, this text will be bold, italic, and highlighted

Toolbar Integration

import { useYooptaEditor } from '@yoopta/editor';

function FormatToolbar() {
  const editor = useYooptaEditor();
  
  return (
    <div className="toolbar">
      <button
        onClick={() => editor.formats.bold.toggle()}
        className={editor.formats.bold.isActive() ? 'active' : ''}
      >
        <BoldIcon />
      </button>
      
      <button
        onClick={() => editor.formats.italic.toggle()}
        className={editor.formats.italic.isActive() ? 'active' : ''}
      >
        <ItalicIcon />
      </button>
      
      <button
        onClick={() => editor.formats.highlight.update({
          color: '#000',
          backgroundColor: '#ffff00',
        })}
      >
        <HighlightIcon />
      </button>
    </div>
  );
}

Type Imports

import type {
  YooptaMark,
  YooptaMarkParams,
  YooptaMarkProps,
  TextFormat,
  SlateElementTextNode,
  ExtendedLeaf,
} from '@yoopta/editor';

import { createYooptaMark } from '@yoopta/editor';

See Also

Build docs developers (and LLMs) love