CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-mantine--tiptap

Rich text editor React component library based on Tiptap with extensive formatting controls and Mantine integration

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

extensions.mddocs/

Extensions

Tiptap extensions with enhanced functionality for links and task lists. These extensions provide additional features beyond the standard Tiptap extensions, including custom keyboard shortcuts and styling integration.

Capabilities

Link Extension

Enhanced Tiptap Link extension with custom keyboard shortcuts and optimized behavior for rich text editing.

/**
 * Enhanced Link extension with keyboard shortcuts
 * Extends @tiptap/extension-link with additional functionality
 * Keyboard shortcut: Ctrl/Cmd + K opens link editor
 */
const Link: Extension;

Features:

  • Keyboard Shortcut: Cmd/Ctrl+K opens link editing interface
  • Click Behavior: Links don't open on click (optimized for editing)
  • Event Integration: Dispatches 'edit-link' window event for UI integration

Usage Example:

import { useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import { RichTextEditor, Link } from "@mantine/tiptap";

function EditorWithLinks() {
  const editor = useEditor({
    extensions: [
      StarterKit,
      Link, // Enhanced Link extension
    ],
    content: '<p>Visit <a href="https://mantine.dev">Mantine</a> for more info!</p>',
  });

  return (
    <RichTextEditor editor={editor}>
      <RichTextEditor.Toolbar>
        <RichTextEditor.ControlsGroup>
          <RichTextEditor.Link />
          <RichTextEditor.Unlink />
        </RichTextEditor.ControlsGroup>
      </RichTextEditor.Toolbar>
      <RichTextEditor.Content />
    </RichTextEditor>
  );
}

TaskList Extension Factory

Factory function that enhances any Tiptap TaskList extension with custom keyboard shortcuts and Mantine-specific styling.

/**
 * Factory function to enhance TaskList extensions
 * Adds keyboard shortcuts and custom styling to any TaskList extension
 * @param TipTapTaskList - The TaskList extension to enhance
 * @returns Enhanced TaskList extension with additional functionality
 */
function getTaskListExtension<T>(TipTapTaskList: T): T;

Features:

  • Keyboard Shortcuts:
    • Cmd/Ctrl + [: Decrease task indentation (lift)
    • Cmd/Ctrl + ]: Increase task indentation (sink)
  • Custom Styling: Applies Mantine-specific CSS classes
  • Generic Support: Works with any TaskList extension implementation

Usage Example:

import { useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import TaskList from "@tiptap/extension-task-list";
import TaskItem from "@tiptap/extension-task-item";
import { RichTextEditor, getTaskListExtension } from "@mantine/tiptap";

function EditorWithTasks() {
  const editor = useEditor({
    extensions: [
      StarterKit,
      // Enhanced TaskList with keyboard shortcuts and styling
      getTaskListExtension(TaskList),
      TaskItem.configure({
        nested: true,
      }),
    ],
    content: `
      <ul data-type="taskList">
        <li data-type="taskItem" data-checked="false">Uncompleted task</li>
        <li data-type="taskItem" data-checked="true">Completed task</li>
        <li data-type="taskItem" data-checked="false">
          Parent task
          <ul data-type="taskList">
            <li data-type="taskItem" data-checked="false">Nested task</li>
          </ul>
        </li>
      </ul>
    `,
  });

  return (
    <RichTextEditor editor={editor}>
      <RichTextEditor.Toolbar>
        <RichTextEditor.ControlsGroup>
          <RichTextEditor.TaskList />
          <RichTextEditor.TaskListSink />
          <RichTextEditor.TaskListLift />
        </RichTextEditor.ControlsGroup>
      </RichTextEditor.Toolbar>
      <RichTextEditor.Content />
    </RichTextEditor>
  );
}

Extension Details

Link Extension Implementation

The Link extension is built on top of @tiptap/extension-link with the following enhancements:

// Internal implementation (for reference)
import TipTapLink from '@tiptap/extension-link';

const Link = TipTapLink.extend({
  addKeyboardShortcuts: () => ({
    'Mod-k': () => {
      // Dispatches custom event for UI integration
      window.dispatchEvent(new Event('edit-link'));
      return true;
    },
  }),
}).configure({ 
  openOnClick: false // Prevents links from opening when clicked
});

Configuration Options:

  • All standard @tiptap/extension-link options are supported
  • openOnClick: false is set by default for better editing experience
  • Additional keyboard shortcuts are automatically added

TaskList Extension Factory Implementation

The factory function enhances TaskList extensions with:

// Internal implementation (for reference)  
const getTaskListExtension = <T>(TipTapTaskList: T): T =>
  (TipTapTaskList as any)
    .extend({
      addKeyboardShortcuts: () => ({
        'Mod-[': ({ editor }: any) => {
          editor.chain().focus().liftListItem('taskItem').run();
          return true;
        },
        'Mod-]': ({ editor }: any) => {
          editor.chain().focus().sinkListItem('taskItem').run();
          return true;
        },
      }),
    })
    .configure({
      HTMLAttributes: {
        class: `mantine-RichTextEditor-taskList`,
      },
    });

Enhancement Features:

  • Keyboard Shortcuts: Standard indentation shortcuts for task management
  • CSS Classes: Mantine-specific classes for consistent styling
  • Generic Implementation: Works with any TaskList extension

Complete Extensions Example

import { useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import TaskList from "@tiptap/extension-task-list";
import TaskItem from "@tiptap/extension-task-item";
import { RichTextEditor, Link, getTaskListExtension } from "@mantine/tiptap";

function FullFeaturedEditor() {
  const editor = useEditor({
    extensions: [
      StarterKit,
      
      // Enhanced Link extension
      Link,
      
      // Enhanced TaskList extension
      getTaskListExtension(TaskList),
      TaskItem.configure({
        nested: true,
        HTMLAttributes: {
          class: 'my-task-item',
        },
      }),
    ],
    content: `
      <h2>Rich Text Editor with Extensions</h2>
      
      <p>This editor supports <a href="https://mantine.dev">enhanced links</a> 
      with keyboard shortcuts (Cmd/Ctrl+K).</p>
      
      <p>Task management with enhanced shortcuts:</p>
      <ul data-type="taskList">
        <li data-type="taskItem" data-checked="false">
          Press Cmd/Ctrl+] to indent this task
        </li>
        <li data-type="taskItem" data-checked="true">
          Press Cmd/Ctrl+[ to outdent this task
        </li>
        <li data-type="taskItem" data-checked="false">
          Parent task
          <ul data-type="taskList">
            <li data-type="taskItem" data-checked="false">Nested subtask</li>
          </ul>
        </li>
      </ul>
    `,
  });

  return (
    <RichTextEditor editor={editor}>
      <RichTextEditor.Toolbar sticky stickyOffset={60}>
        {/* Link controls */}
        <RichTextEditor.ControlsGroup>
          <RichTextEditor.Link />
          <RichTextEditor.Unlink />
        </RichTextEditor.ControlsGroup>

        {/* Task controls */}
        <RichTextEditor.ControlsGroup>
          <RichTextEditor.TaskList />
          <RichTextEditor.TaskListSink />
          <RichTextEditor.TaskListLift />
        </RichTextEditor.ControlsGroup>
      </RichTextEditor.Toolbar>

      <RichTextEditor.Content />
    </RichTextEditor>
  );
}

Extension Integration

Event Handling

The Link extension dispatches custom events that can be handled by your application:

useEffect(() => {
  const handleEditLink = () => {
    console.log('Link editing triggered');
    // Custom link editing logic
  };

  window.addEventListener('edit-link', handleEditLink);
  
  return () => {
    window.removeEventListener('edit-link', handleEditLink);
  };
}, []);

Styling Integration

Extensions automatically integrate with Mantine's styling system:

// TaskList extension applies these classes automatically
.mantine-RichTextEditor-taskList {
  /* Mantine task list styling */
}

// You can override with custom styles
<RichTextEditor
  styles={{
    taskList: {
      marginLeft: '1rem',
      '& li': {
        marginBottom: '0.5rem',
      },
    },
  }}
>
  {/* editor content */}
</RichTextEditor>

Custom Extension Development

You can create your own enhanced extensions using similar patterns:

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

const MyCustomExtension = Extension.create({
  name: 'myCustom',
  
  addKeyboardShortcuts() {
    return {
      'Mod-Shift-x': () => {
        // Custom functionality
        return true;
      },
    };
  },
  
  addOptions() {
    return {
      HTMLAttributes: {
        class: 'mantine-RichTextEditor-custom',
      },
    };
  },
});

// Use with RichTextEditor
const editor = useEditor({
  extensions: [StarterKit, MyCustomExtension],
});

Required Dependencies

Extensions require specific Tiptap packages:

  • Link Extension:

    • @tiptap/extension-link (peer dependency)
    • Automatically imported when using Link from @mantine/tiptap
  • TaskList Extension Factory:

    • @tiptap/extension-task-list
    • @tiptap/extension-task-item
    • Must be installed and passed to getTaskListExtension()

Best Practices

Extension Ordering

const editor = useEditor({
  extensions: [
    StarterKit, // Base extensions first
    Link, // Enhanced Link extension
    getTaskListExtension(TaskList), // Enhanced TaskList
    TaskItem, // TaskItem after TaskList
    // Other extensions...
  ],
});

Configuration

// Configure enhanced extensions
const editor = useEditor({
  extensions: [
    StarterKit,
    Link, // Uses default configuration
    getTaskListExtension(
      TaskList.configure({
        itemTypeName: 'taskItem',
        HTMLAttributes: {
          class: 'custom-task-list',
        },
      })
    ),
  ],
});

TypeScript Support

import type { Extension } from '@tiptap/core';
import { Link, getTaskListExtension } from '@mantine/tiptap';

// Extensions have proper TypeScript support
const linkExtension: Extension = Link;
const taskListExtension: Extension = getTaskListExtension(TaskList);

docs

advanced-controls.md

context-hooks.md

core-components.md

extensions.md

index.md

labels-i18n.md

structure-controls.md

text-formatting.md

tile.json