Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 268 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
# Architecture Overview

This document describes the high-level architecture of @gravity-ui/markdown-editor.

## System Diagram

```mermaid
flowchart TB
subgraph Public API
useMarkdownEditor[useMarkdownEditor Hook]
MarkdownEditorView[MarkdownEditorView Component]
end

subgraph Bundle Layer
BundleEditor[Editor Instance]
Config[Toolbar & Preset Config]
end

subgraph Core Engine
WysiwygEditor[WysiwygEditor]
ContentHandler[ContentHandler]
ExtensionsManager[ExtensionsManager]
end

subgraph Editor Modes
ProseMirror[ProseMirror\nWYSIWYG Mode]
CodeMirror[CodeMirror 6\nMarkup Mode]
end

subgraph Extensions
MarkdownExt[Markdown Extensions\nheadings, lists, code, tables]
YFMExt[YFM Extensions\nalerts, tabs, notes, cuts]
BehaviorExt[Behavior Extensions\nhistory, clipboard, drag-drop]
end

subgraph Parsing Layer
MarkdownIt[markdown-it\nParser/Serializer]
end

useMarkdownEditor --> BundleEditor
MarkdownEditorView --> BundleEditor
BundleEditor --> Config
BundleEditor --> WysiwygEditor
WysiwygEditor --> ContentHandler
WysiwygEditor --> ExtensionsManager
ExtensionsManager --> MarkdownExt
ExtensionsManager --> YFMExt
ExtensionsManager --> BehaviorExt
ContentHandler --> MarkdownIt
WysiwygEditor --> ProseMirror
BundleEditor --> CodeMirror
MarkdownIt --> ProseMirror
MarkdownIt --> CodeMirror
```

## Main Components

### 1. Public API (`/src/bundle`)

The consumer-facing React API:

| Export | Purpose |
|--------|---------|
| `useMarkdownEditor(options)` | Hook that creates and configures an editor instance |
| `MarkdownEditorView` | React component that renders the editor UI |
| `Editor` | Bundle-level editor class wrapping the core |

### 2. Core Engine (`/src/core`)

The heart of the editor:

| Component | Purpose |
|-----------|---------|
| `WysiwygEditor` | ProseMirror editor wrapper with state management |
| `ContentHandler` | Converts between Markdown ↔ ProseMirror document |
| `ExtensionBuilder` | Configures extensions during initialization |
| `ExtensionsManager` | Manages active extensions at runtime |

### 3. Editor Modes

```mermaid
flowchart LR
subgraph WYSIWYG Mode
PM[ProseMirror]
PMDoc[Document Model]
PMView[Editor View]
PM --> PMDoc --> PMView
end

subgraph Markup Mode
CM[CodeMirror 6]
CMState[Editor State]
CMView[Editor View]
CM --> CMState --> CMView
end

subgraph Split Mode
Both[Both editors\nside-by-side]
end

ContentHandler[ContentHandler\nMarkdown Serialization]

PMDoc <--> ContentHandler
CMState <--> ContentHandler
```

| Mode | Engine | Description |
|------|--------|-------------|
| WYSIWYG | ProseMirror | Rich text editing with toolbar |
| Markup | CodeMirror 6 | Raw markdown with syntax highlighting |
| Split | Both | Side-by-side with synchronized content |

### 4. Extension System (`/src/extensions`)

Extensions are modular plugins that add functionality:

```mermaid
flowchart TB
subgraph Extension Structure
Spec[Extension Spec]
Node[Node Type]
Mark[Mark Type]
Commands[Commands]
Keymap[Keymaps]
Toolbar[Toolbar Items]
Parser[Parser Rules]
Serializer[Serializer Rules]
end

Spec --> Node
Spec --> Mark
Spec --> Commands
Spec --> Keymap
Spec --> Toolbar
Spec --> Parser
Spec --> Serializer
```

**Extension Categories:**

| Category | Location | Examples |
|----------|----------|----------|
| Markdown | `/extensions/markdown` | Heading, Bold, Italic, Link, Image, CodeBlock, Table |
| YFM | `/extensions/yfm` | Alerts (Note/Tip/Warning), Tabs, Cuts, File |
| Behavior | `/extensions/behavior` | History, Clipboard, Placeholder, Selection |
| Additional | `/extensions/additional` | HTML, LaTeX, Mermaid, GPT |

### 5. Presets (`/src/presets`)

Pre-configured extension bundles:

| Preset | Description |
|--------|-------------|
| `zero` | Minimal - just paragraphs and line breaks |
| `commonmark` | Standard CommonMark syntax |
| `default` | CommonMark + common extras |
| `yfm` | Yandex Flavored Markdown |
| `full` | All available extensions |

### 6. UI Components

```mermaid
flowchart TB
subgraph Toolbar
FlexToolbar[FlexToolbar]
ToolbarButton[ToolbarButton]
ToolbarGroup[ToolbarGroup]
ToolbarListButton[ToolbarListButton]
end

subgraph Forms
LinkForm[LinkForm]
ImageForm[ImageForm]
FileForm[FileForm]
end

subgraph View
EditorComponent[Editor Component]
ModeSwitch[Mode Switcher]
SplitView[Split View]
end

FlexToolbar --> ToolbarButton
FlexToolbar --> ToolbarGroup
FlexToolbar --> ToolbarListButton
EditorComponent --> FlexToolbar
EditorComponent --> ModeSwitch
EditorComponent --> SplitView
ToolbarButton --> Forms
```

## Data Flow

### Content Flow

```mermaid
sequenceDiagram
participant User
participant View as MarkdownEditorView
participant Editor as Editor Instance
participant PM as ProseMirror
participant Handler as ContentHandler
participant MD as markdown-it

User->>View: Type in WYSIWYG
View->>PM: Input event
PM->>PM: Update document
PM->>Editor: State change

User->>View: Switch to Markup mode
View->>Editor: Mode change
Editor->>Handler: Serialize
Handler->>MD: ProseMirror → Markdown
MD-->>Handler: Markdown string
Handler-->>Editor: Content for CodeMirror

User->>View: getValue()
View->>Editor: getValue()
Editor->>Handler: Serialize current state
Handler-->>Editor: Markdown string
Editor-->>View: Return markdown
```

### Event System

The editor emits events for external integration:

| Event | Trigger |
|-------|---------|
| `change` | Content modified |
| `submit` | Ctrl/Cmd+Enter pressed |
| `cancel` | Escape pressed |
| `toolbar-action` | Toolbar button clicked |
| `mode-change` | WYSIWYG ↔ Markup switch |

## Directory Structure

```
src/
├── bundle/ # Public React API
│ ├── Editor.ts
│ ├── useMarkdownEditor.ts
│ ├── MarkdownEditorView.tsx
│ └── config/ # Toolbar configurations
├── core/ # Editor engine
│ ├── Editor.ts # WysiwygEditor
│ ├── ContentHandler.ts
│ ├── ExtensionBuilder.ts
│ ├── ExtensionsManager.ts
│ └── markdown/ # Parsing utilities
├── extensions/ # Plugin system
│ ├── base/ # Base implementations
│ ├── markdown/ # Standard markdown
│ ├── yfm/ # YFM-specific
│ ├── behavior/ # Editor behaviors
│ └── additional/ # Optional (HTML, LaTeX, etc.)
├── presets/ # Extension bundles
├── toolbar/ # Toolbar components
├── forms/ # Dialog components
├── view/ # React utilities
├── pm/ # ProseMirror re-exports
├── cm/ # CodeMirror re-exports
├── utils/ # Shared utilities
└── styles/ # SCSS stylesheets
```
83 changes: 83 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# CLAUDE.md
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shevnv

I suggest to

  1. delete metadata
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
  1. move files to gravity-ui/markdown-editor/docs


This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

@gravity-ui/markdown-editor is a React-based markdown editor component that combines WYSIWYG and Markup modes. It uses ProseMirror for rich text editing and CodeMirror for markup editing. Supports standard Markdown and YFM (Yandex Flavored Markdown) syntax.

## Common Commands

```bash
npm start # Start Storybook dev server (port 8888)
npm run build # Build for production
npm run typecheck # TypeScript type checking
npm run lint # Run all linters (ESLint, Stylelint, Prettier)
npm test # Run Jest unit tests
npm run test:watch # Run tests in watch mode
npm run playwright # Run Playwright E2E tests
```

## Architecture

### Core Modules (`/src`)

- **`/bundle`** - High-level React API
- `useMarkdownEditor()` hook creates editor instance
- `MarkdownEditorView` component renders the editor
- `/config` contains toolbar and preset configurations

- **`/core`** - Core editor engine
- `Editor.ts` - WysiwygEditor class (ProseMirror-based)
- `ContentHandler.ts` - Markdown serialization/deserialization
- `ExtensionBuilder.ts` / `ExtensionsManager.ts` - Extension system

- **`/extensions`** - Built-in extensions organized by category
- `/base` - Base extension implementations
- `/markdown` - Standard markdown features (headings, lists, code blocks, tables)
- `/yfm` - YFM-specific features (alerts, tabs, notes)
- `/behavior` - Editor behaviors (history, links, images)

- **`/pm`** - ProseMirror abstraction layer (re-exports prosemirror-* modules)
- **`/cm`** - CodeMirror 6 abstraction layer (re-exports @codemirror/* modules)

- **`/presets`** - Editor configurations: `default`, `full`, `yfm`, `commonmark`, `zero`

- **`/toolbar`** - Toolbar UI components
- **`/forms`** - Dialog/form components for links, images, files
- **`/view`** - React view layer (components, hooks, HOCs)

### Package Exports

The package provides subpath exports for tree-shaking:
- `@gravity-ui/markdown-editor` - Main bundle
- `@gravity-ui/markdown-editor/core` - Core engine only
- `@gravity-ui/markdown-editor/extensions` - Extension system
- `@gravity-ui/markdown-editor/view` - React components
- `@gravity-ui/markdown-editor/cm/*` - CodeMirror utilities
- `@gravity-ui/markdown-editor/pm/*` - ProseMirror utilities

### Editor Modes

- **WYSIWYG**: ProseMirror-based rich editing
- **Markup**: CodeMirror-based raw markdown editing
- **Split**: Both modes side-by-side with synchronized content

### Basic Usage Pattern

```tsx
import {useMarkdownEditor, MarkdownEditorView} from '@gravity-ui/markdown-editor';

function Editor() {
const editor = useMarkdownEditor({allowHTML: false});
return <MarkdownEditorView editor={editor} />;
}
```

## Tech Stack

- React 16-19, TypeScript, SCSS
- ProseMirror (WYSIWYG), CodeMirror 6 (Markup)
- markdown-it (parsing), @gravity-ui/* UI components
- Jest (unit tests), Playwright (E2E tests)
- Gulp (build), Storybook (development/docs)
Loading