CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tiptap--extension-focus

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

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@tiptap/extensions@3.4.x#focus
Publish Source
CLI
Badge
tessl/npm-tiptap--extension-focus badge