terraphim / terraphim/terraphim-ai

[Research] TipTap/ProseMirror Integration with Web Components

Open
#225 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

research web-components
Dominant language
Rust
Stars
62
Forks
5
Avg merge
2h 27m
Merged PRs (30d)
1

Description

Research Objective

Investigate strategies for integrating TipTap/ProseMirror rich text editor into Web Components for NovelWrapper migration.

Current State (NovelWrapper.svelte)

  • Using @paralect/novel-svelte wrapper
  • TipTap core with Markdown extension
  • Custom Terraphim autocomplete suggestion plugin
  • Configurable output format (HTML/Markdown)
  • Role-based autocomplete from knowledge graph
  • Connection testing and index building

Reference: desktop/src/lib/Editor/NovelWrapper.svelte

Research Questions

  1. How to wrap TipTap editor in Web Component?
  2. Shadow DOM vs Light DOM for editor content?
  3. How to maintain custom suggestion plugin?
  4. Event handling across component boundary?
  5. Performance implications of Web Component wrapper?

Integration Approaches

Approach 1: Light DOM Editor

Mount TipTap editor in Light DOM slot within Web Component.

Pros:

  • Full TipTap functionality
  • Standard CSS styling
  • Plugin compatibility guaranteed
  • Event handling straightforward

Cons:

  • Less encapsulation
  • Style leakage possible
  • Not truly isolated

Implementation:

class TerraphimEditor extends HTMLElement {
  connectedCallback() {
    const slot = this.querySelector('slot[name="editor"]');
    this.editor = new Editor({
      element: slot,
      extensions: [...]
    });
  }
}
Approach 2: Shadow DOM with adoptedStyleSheets

Mount editor in Shadow DOM, inject styles via Constructable Stylesheets.

Pros:

  • True encapsulation
  • Style isolation
  • Component distribution

Cons:

  • Need to manage all TipTap CSS
  • Plugin styles may break
  • contenteditable complexity

Implementation:

class TerraphimEditor extends HTMLElement {
  connectedCallback() {
    const shadow = this.attachShadow({ mode: 'open' });
    const sheet = new CSSStyleSheet();
    sheet.replaceSync(tiptapStyles);
    shadow.adoptedStyleSheets = [sheet];
    
    this.editor = new Editor({
      element: shadow.querySelector('.editor'),
      extensions: [...]
    });
  }
}
Approach 3: Iframe Isolation (Nuclear Option)

Run editor in iframe for complete isolation.

Pros:

  • Maximum isolation
  • No Shadow DOM issues
  • Full control

Cons:

  • Performance overhead
  • Communication complexity
  • Loading time
  • Not practical for our use case

Custom Extension Migration

TerraphimSuggestion Plugin

Current: Svelte component aware, uses stores
Challenge: How to pass reactive role/suggestions to Web Component?

Solutions:

  1. Properties + Events:

    • Pass role as property
    • Emit custom events for suggestions
    • Plugin queries parent Web Component
  2. Service Layer:

    • Keep novelAutocompleteService as singleton
    • Plugin calls service directly
    • Web Component configures service
  3. Suggestion Provider Pattern:

    • Define interface for suggestion provider
    • Inject provider into plugin
    • Web Component implements provider

Key Features to Maintain

From Current Implementation:
  • TipTap editor with Markdown support
  • Custom autocomplete with / trigger
  • Knowledge graph suggestions
  • HTML vs Markdown output toggle
  • Read-only mode
  • Connection testing
  • Index building
  • Role-based suggestions
  • Tauri vs Web backend switching
New Requirements:
  • Web Component API
  • Shadow DOM compatible (if chosen)
  • Accessible
  • Theme-aware
  • No Svelte dependencies

Technical Challenges

Challenge 1: ProseMirror DOM Manipulation

Problem: ProseMirror directly manipulates DOM, needs real DOM nodes
Solution: Use Light DOM or careful Shadow DOM setup

Challenge 2: Plugin Context

Problem: Plugins need access to app context (role, backend)
Solution: Dependency injection or context provider pattern

Challenge 3: Style Injection

Problem: TipTap styles must be available
Solution: Bundle styles with component or use adoptedStyleSheets

Challenge 4: Markdown Extension

Problem: tiptap-markdown extension compatibility
Solution: Test in Web Component context, may need wrapper

Libraries to Evaluate

1. @tiptap/core (Current)
  • Status: Framework-agnostic
  • Web Component support: Should work
  • Action: Test compatibility
2. Alternative Editors (If TipTap Fails)
a) Quill.js
  • Pros: Simpler, well-documented
  • Cons: Less extensible, no Markdown native
b) ProseMirror (Direct)
  • Pros: Maximum control
  • Cons: Low-level, complex
c) EditorJS
  • Pros: Block-based, modern
  • Cons: Different paradigm, JSON output
d) CodeMirror 6
  • Pros: Excellent for code/markdown
  • Cons: Not WYSIWYG

Acceptance Criteria

  • TipTap integration approach selected
  • Shadow DOM decision documented
  • Custom plugin migration path defined
  • Prototype Web Component editor
  • Performance comparison (render time, typing latency)
  • Markdown extension compatibility verified
  • Autocomplete integration working
  • Accessibility verified

References

  • Current editor: desktop/src/lib/Editor/NovelWrapper.svelte
  • Custom plugin: desktop/src/lib/Editor/TerraphimSuggestion.ts
  • Autocomplete service: desktop/src/lib/services/novelAutocompleteService.ts

Documentation

Findings will be documented in: .docs/research-tiptap-integration.md

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read desktop/src/lib/Editor/NovelWrapper.svelte, desktop/src/lib/Editor/TerraphimSuggestion.ts, and desktop/src/lib/services/novelAutocompleteService.ts to understand the current editor, plugin, and service boundaries. Evaluate the listed Web Component approaches and document the selected integration, Shadow DOM decision, migration path, prototype findings, compatibility, performance, accessibility, and autocomplete results in .docs/research-tiptap-integration.md.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
frontend, web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.