memos/web/src/components/MemoEditor
memoclaw acddef1f3d
fix(api): switch user resource names to usernames (#5779)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
2026-03-25 09:11:17 +08:00
..
components refactor(web): consolidate memo metadata components into MemoMetadata (#5755) 2026-03-21 09:04:15 +08:00
Editor fix: toggle focus mode do not reset editor height (#5504) 2026-03-04 22:13:58 +08:00
hooks fix(api): switch user resource names to usernames (#5779) 2026-03-25 09:11:17 +08:00
services refactor(web): improve MemoView and MemoEditor maintainability (#5754) 2026-03-21 07:20:18 +08:00
state refactor(web): improve MemoView and MemoEditor maintainability (#5754) 2026-03-21 07:20:18 +08:00
Toolbar refactor(web): consolidate memo metadata components into MemoMetadata (#5755) 2026-03-21 09:04:15 +08:00
types refactor(web): consolidate memo metadata components into MemoMetadata (#5755) 2026-03-21 09:04:15 +08:00
constants.ts refactor(web): improve MemoView and MemoEditor maintainability (#5754) 2026-03-21 07:20:18 +08:00
index.tsx refactor(web): improve MemoView and MemoEditor maintainability (#5754) 2026-03-21 07:20:18 +08:00
README.md refactor(editor): complete state machine and services migration 2025-12-23 08:38:02 +08:00

MemoEditor Architecture

Overview

MemoEditor uses a three-layer architecture for better separation of concerns and testability.

Architecture

┌─────────────────────────────────────────┐
│   Presentation Layer (Components)       │
│   - EditorToolbar, EditorContent, etc.  │
└─────────────────┬───────────────────────┘
                  │
┌─────────────────▼───────────────────────┐
│   State Layer (Reducer + Context)       │
│   - state/, useEditorContext()          │
└─────────────────┬───────────────────────┘
                  │
┌─────────────────▼───────────────────────┐
│   Service Layer (Business Logic)        │
│   - services/ (pure functions)          │
└─────────────────────────────────────────┘

Directory Structure

MemoEditor/
├── state/                  # State management (reducer, actions, context)
├── services/              # Business logic (pure functions)
├── components/            # UI components
├── hooks/                 # React hooks (utilities)
├── Editor/               # Core editor component
├── Toolbar/              # Toolbar components
├── constants.ts
└── types/

Key Concepts

State Management

Uses useReducer + Context for predictable state transitions. All state changes go through action creators.

Services

Pure TypeScript functions containing business logic. No React hooks, easy to test.

Components

Thin presentation components that dispatch actions and render UI.

Usage

import MemoEditor from "@/components/MemoEditor";

<MemoEditor
  memoName="memos/123"
  onConfirm={(name) => console.log('Saved:', name)}
  onCancel={() => console.log('Cancelled')}
/>

Testing

Services are pure functions - easy to unit test without React.

const state = mockEditorState();
const result = await memoService.save(state, { memoName: 'memos/123' });