4.6 KiB
4.6 KiB
Tasks: enterprise-react-rich-text
Change ID: enterprise-react-rich-text
Package: @suaveplan/react-rich-text
Target path: react/media/react-rich-text
Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/react-translate
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Scaffold
- Create directory tree. Write
package.jsonat0.1.0,tsconfig.json,vitest.config.ts, scripts. - Dependencies:
@suaveplan/error workspace:^,@suaveplan/react-translate workspace:^,@tiptap/core catalog:editor,@tiptap/react catalog:editor,@tiptap/starter-kit catalog:editor,@tiptap/extension-mention catalog:editor,@tiptap/extension-placeholder catalog:editor,@tiptap/extension-link catalog:editor,@tiptap/pm catalog:editor,@tiptap/suggestion catalog:editor,zod catalog:forms,@opentelemetry/api catalog:observability,tslib catalog:build.
2. Error codes and types
- Define
RichTextError; codes:RICH_TEXT_INIT_FAILED,RICH_TEXT_PARSE_FAILED. - Define all types:
FormatState,FormatMark,BlockType,HeadingLevel,MarkdownShortcutRule,MentionItem,SlashCommand,SlashCommandCategory.
3. EditorEngine
buildExtensions(options)— assembles Tiptap extensions (StarterKit + Mention + Placeholder + Link + custom slash-command + markdown shortcuts). ThrowsRichTextError(RICH_TEXT_INIT_FAILED)on invalid config.htmlToMarkdown(html: string): string,markdownToHtml(md: string): string— round-trip via regex transforms.filterSlashCommands(query, commands),groupCommandsByCategory(commands),executeSlashCommand(cmd, editor).- Write
editor-engine.test.ts(≤500 lines): extensions build, htmlToMarkdown/markdownToHtml round-trip, filterSlashCommands, groupByCategory, executeSlashCommand.{ timeout: 10000 }. - Write
editor-engine.md.
4. Hooks
useRichText
- Creates Tiptap
Editorinstance; returns{ editor, html, markdown, isEmpty }. OTelrich_text.submitspan on submit. - Write test + md.
useMentions
- Provides suggestion callbacks for
@tiptap/extension-mention; acceptsonSearch(query): Promise<MentionItem[]>. - Write test + md.
useSlashCommands
- Registers slash-command suggestion plugin; returns
{ commands, filter, execute }. - Write test + md.
5. Components
EditorContent
<EditorContent editor={editor} />— renders Tiptap editor area.- Write test, stories (default, with-content, read-only, playground), md.
Toolbar
- Bold/italic/underline/strike/heading/list/quote/code/link buttons wired to
editor.chain().useTranslationfor tooltips. - Write test, stories (default, formatting-applied, playground), md.
BubbleMenu
- Selection-anchored menu using Tiptap
BubbleMenu. Bold/italic/link buttons. - Write test, stories (default, formatting, playground — previously missing), md.
SlashCommandMenu
- Tiptap suggestion dropdown; renders filtered
SlashCommandlist. - Write test, stories, md.
MentionList
- Mention suggestion dropdown with avatar + name.
- Write test, stories, md.
RichTextEditor
- Composes all components. Accepts
initialContent,placeholder,onUpdate,onSubmit,mentionSearch. - Write test, stories (default, with-mentions, with-slash-commands, markdown, playground), md.
6. E2E
e2e/rich-text.spec.ts— Playwright:- Type text, click Bold in toolbar →
<strong>in output. - Type
/→ slash menu appears; select "Heading 1" → H1 applied. - Type
@→ mention list appears; click item → mention inserted.
- Type text, click Bold in toolbar →
7. Verify and publish
bunx turbo lint typecheck test --filter=@suaveplan/react-rich-text— green.bunx turbo test:coverage --filter=@suaveplan/react-rich-text— 100%.bun scripts/publish.ts --package @suaveplan/react-rich-text.- Archive change folder.