or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-tiptap--extension-focus

Tiptap extension that allows you to add a class to the focused node with configurable focus modes

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@tiptap/extensions@3.4.x#focus

To install, run

npx @tessl/cli install tessl/npm-tiptap--extension-focus@3.4.0

index.mddocs/

Tiptap Focus Extension

The Focus extension allows you to add CSS classes to focused nodes in a Tiptap editor, providing visual focus indicators that enhance user experience and accessibility. It operates as a ProseMirror plugin that decorates nodes based on cursor position, offering three different focus modes for various use cases.

Package Information

  • Package Name: @tiptap/extensions/focus
  • Package Type: npm (TypeScript extension)
  • Language: TypeScript
  • Installation: npm install @tiptap/extensions

Core Imports

import { Focus, FocusOptions } from "@tiptap/extensions";

For CommonJS:

const { Focus, FocusOptions } = require("@tiptap/extensions");

Sub-path imports (also supported):

import { Focus, FocusOptions } from "@tiptap/extensions/focus";

Basic Usage

import { Editor } from "@tiptap/core";
import { Focus } from "@tiptap/extensions";

// Basic usage with default options
const editor = new Editor({
  extensions: [
    Focus,
    // ... other extensions
  ],
  content: "<p>Your content here</p>",
});

// Custom configuration
const editor = new Editor({
  extensions: [
    Focus.configure({
      className: 'is-focused',
      mode: 'deepest',
    }),
    // ... other extensions
  ],
  content: "<p>Your content here</p>",
});

Architecture

The Focus extension integrates with Tiptap's extension system and uses ProseMirror's decoration API to efficiently add CSS classes to DOM elements without re-rendering content. Key components:

  • Extension Class: Extends Tiptap's base Extension class with focus-specific configuration
  • ProseMirror Plugin: Implements the actual focus detection and decoration logic
  • Decoration System: Uses ProseMirror's DecorationSet for performant DOM manipulation
  • Focus Detection: Analyzes document structure and cursor position to determine focused nodes

Capabilities

Focus Extension

Creates a Tiptap extension that adds CSS classes to focused nodes based on cursor position.

import { Extension } from "@tiptap/core";

/**
 * Focus extension that adds CSS classes to focused nodes
 * Extends Tiptap's base Extension class with FocusOptions configuration
 */
const Focus: Extension<FocusOptions>;

Focus Configuration

Configures the Focus extension with custom options.

/**
 * Configure the Focus extension with custom options
 * @param options - Configuration options for focus behavior
 * @returns Configured Focus extension instance
 */
Focus.configure(options: Partial<FocusOptions>): Extension<FocusOptions>;

Focus Mode: All

Marks all nodes in the selection path as focused (default behavior).

// Configuration for 'all' mode
Focus.configure({
  mode: 'all',
  className: 'has-focus'
})

Focus Mode: Deepest

Marks only the deepest (innermost) node in the selection as focused.

// Configuration for 'deepest' mode
Focus.configure({
  mode: 'deepest',
  className: 'has-focus'
})

Focus Mode: Shallowest

Marks only the shallowest (outermost) node in the selection as focused.

// Configuration for 'shallowest' mode
Focus.configure({
  mode: 'shallowest',
  className: 'has-focus'
})

Types

/**
 * Configuration options for the Focus extension
 */
interface FocusOptions {
  /**
   * The CSS class name that should be added to the focused node
   * @default 'has-focus'
   * @example 'is-focused'
   */
  className: string;

  /**
   * The mode by which the focused node is determined
   * - 'all': All nodes in the selection path are marked as focused
   * - 'deepest': Only the innermost node is marked as focused
   * - 'shallowest': Only the outermost node is marked as focused
   * @default 'all'
   */
  mode: 'all' | 'deepest' | 'shallowest';
}

Usage Examples

Custom CSS Class

import { Editor } from "@tiptap/core";
import { Focus } from "@tiptap/extensions";

const editor = new Editor({
  extensions: [
    Focus.configure({
      className: 'editor-focused-node'
    })
  ],
  content: '<p>Your content here</p>',
});

Deepest Node Focus

// Only highlight the innermost focused element
const editor = new Editor({
  extensions: [
    Focus.configure({
      mode: 'deepest',
      className: 'deeply-focused'
    })
  ],
  content: '<p>Your content here</p>',
});

Accessibility Enhancement

// Use ARIA-friendly class names for screen readers
const editor = new Editor({
  extensions: [
    Focus.configure({
      className: 'aria-current-element',
      mode: 'deepest'
    })
  ],
  content: '<p>Your content here</p>',
});

CSS Styling

/* Style focused nodes */
.has-focus {
  outline: 2px solid #007acc;
  outline-offset: 2px;
}

/* Different styles for different focus modes */
.deeply-focused {
  background-color: rgba(0, 122, 204, 0.1);
  border-radius: 4px;
}

.aria-current-element {
  box-shadow: 0 0 0 2px #007acc;
}

Integration Requirements

The Focus extension requires:

  • Tiptap Core: @tiptap/core for base Extension class
  • ProseMirror State: @tiptap/pm/state for Plugin and PluginKey
  • ProseMirror View: @tiptap/pm/view for Decoration and DecorationSet
  • Editor Instance: Must be used within a Tiptap Editor configuration

Behavior Notes

  • Focus indicators only appear when the editor is both editable and focused
  • The extension automatically handles cursor movement and selection changes
  • CSS classes are applied and removed dynamically as focus changes
  • Performance is optimized through ProseMirror's decoration system
  • Works with all standard Tiptap nodes and marks