CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tiptap--extensions

Collection of utility extensions for Tiptap rich text editor including character counting, placeholders, focus management, and history controls

Pending
Overview
Eval results
Files

navigation-interaction.mddocs/

Navigation and Interaction

Extensions that enhance cursor movement, gap navigation, and user interaction patterns within the editor.

Capabilities

Gap Cursor Extension

Enables cursor placement in gaps between block nodes where no content normally exists, improving navigation between structural elements.

/**
 * Gap cursor extension for cursor placement between block nodes
 */
const Gapcursor: Extension;

declare module '@tiptap/core' {
  interface NodeConfig<Options, Storage> {
    /** Configure whether this node type allows gap cursor placement */
    allowGapCursor?: boolean | null | ((this: {
      name: string;
      options: Options;
      storage: Storage;
      parent: ParentConfig<NodeConfig<Options>>['allowGapCursor'];
    }) => boolean | null);
  }
}

Usage Examples:

import { Gapcursor } from "@tiptap/extensions/gap-cursor";

// Enable gap cursor
const editor = new Editor({
  extensions: [
    Gapcursor,
  ],
});

// Configure nodes to allow/disallow gap cursor
import { Node } from "@tiptap/core";

const CustomBlock = Node.create({
  name: 'customBlock',
  
  addOptions() {
    return {
      allowGapCursor: true, // Allow gap cursor around this node
    };
  },
  
  // Node definition...
});

// Dynamic allowGapCursor configuration
const ConditionalNode = Node.create({
  name: 'conditionalNode',
  
  addOptions() {
    return {
      allowGapCursor: function() {
        // Custom logic to determine gap cursor allowance
        return this.options.someCondition === true;
      },
    };
  },
});

Gap Cursor Behavior:

  • Allows cursor placement in gaps between block elements
  • Useful for navigating between complex block structures
  • Integrates with ProseMirror's gap cursor plugin
  • Node types can opt-in or opt-out of gap cursor behavior
  • Provides better UX for structured document editing

Selection Extension

Provides custom styling for text selections when the editor is not focused, enhancing visual feedback for users.

/**
 * Selection extension for custom selection styling when unfocused
 */
const Selection: Extension<SelectionOptions> & {
  /** Default export variant */
  default: Extension<SelectionOptions>;
};

type SelectionOptions = {
  /** CSS class name applied to selected text (default: 'selection') */
  className: string;
}

Usage Examples:

import { Selection } from "@tiptap/extensions/selection";

// Basic selection styling
const editor = new Editor({
  extensions: [
    Selection.configure({
      className: 'unfocused-selection',
    }),
  ],
});

// Using with CSS for visual styling
const styledEditor = new Editor({
  extensions: [
    Selection.configure({
      className: 'custom-highlight',
    }),
  ],
});

// CSS to style the selection
/*
.custom-highlight {
  background-color: rgba(0, 123, 255, 0.3);
  border-radius: 2px;
}
*/

Selection Features:

  • Unfocused Only: Only shows custom selection when editor loses focus
  • Text Selection Only: Ignores empty selections and node selections
  • Drag Awareness: Hides during drag and drop operations
  • Automatic Cleanup: Removes styling when editor regains focus
  • CSS Integration: Works with standard CSS for visual customization

Interaction Patterns

Both extensions enhance the user interaction model:

Gap Cursor Interaction:

  • Click between blocks to position cursor in gaps
  • Keyboard navigation through document structure
  • Visual feedback for valid gap cursor positions
  • Enhanced accessibility for screen readers

Selection Interaction:

  • Maintains visual selection state when editor loses focus
  • Provides clear indication of selected content
  • Supports multi-range selections
  • Compatible with browser native selection APIs
// Combined usage for enhanced navigation
import { Gapcursor, Selection } from "@tiptap/extensions";

const editor = new Editor({
  extensions: [
    Gapcursor, // Enable gap navigation
    Selection.configure({
      className: 'persistent-selection', // Show selections when unfocused
    }),
  ],
});

// Enhanced interaction with both extensions
editor.on('focus', () => {
  console.log('Editor focused - selection styling removed');
});

editor.on('blur', () => {
  console.log('Editor blurred - selection styling applied');
});

Install with Tessl CLI

npx tessl i tessl/npm-tiptap--extensions

docs

document-structure.md

index.md

navigation-interaction.md

text-analysis.md

visual-enhancement.md

tile.json