Tips & Tricks

Cara Build a Rich Text Editor dengan Claude Code

Pelajari cara build a rich text editor menggunakan Claude Code. Dilengkapi contoh kode praktis dan panduan langkah demi langkah.

pembangunan リッチテキストeditor

リッチテキストeditor CMS、メールpembuatan、dokumenEdit dll.多く aplikasi diperlukan dan されます 、一 dari pembangunan 非常 kompleks.Claude Code 使えば、Tiptap dll. library ベース 、用途 合ったeditor 素早くカスタマイズ bisa dilakukan.

editorpembangunan Tiptapベース

> Tiptap 使ったリッチテキストeditor buatkan.
> 太字、イタリック、リスト、リンク、gambar挿入 support.
import { useEditor, EditorContent } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import Link from '@tiptap/extension-link';
import Image from '@tiptap/extension-image';

function RichTextEditor({ content, onChange }: { content: string; onChange: (html: string) => void }) {
  const editor = useEditor({
    extensions: [
      StarterKit,
      Link.configure({ openOnClick: false }),
      Image.configure({ inline: true }),
    ],
    content,
    onUpdate: ({ editor }) => {
      onChange(editor.getHTML());
    },
  });

  if (!editor) return null;

  return (
    <div className="border rounded-lg overflow-hidden">
      <Toolbar editor={editor} />
      <EditorContent editor={editor} className="prose max-w-none p-4 min-h-[200px]" />
    </div>
  );
}

implementasi toolsバー

import { Editor } from '@tiptap/react';

function Toolbar({ editor }: { editor: Editor }) {
  const addLink = () => {
    const url = window.prompt('URL input');
    if (url) editor.chain().focus().setLink({ href: url }).run();
  };

  const addImage = () => {
    const url = window.prompt('gambarURL input');
    if (url) editor.chain().focus().setImage({ src: url }).run();
  };

  return (
    <div className="flex gap-1 p-2 border-b bg-gray-50" role="toolbar" aria-label="書式pengaturan">
      <ToolButton
        active={editor.isActive('bold')}
        onClick={() => editor.chain().focus().toggleBold().run()}
        label="太字"
      >B</ToolButton>
      <ToolButton
        active={editor.isActive('italic')}
        onClick={() => editor.chain().focus().toggleItalic().run()}
        label="斜体"
      >I</ToolButton>
      <ToolButton
        active={editor.isActive('bulletList')}
        onClick={() => editor.chain().focus().toggleBulletList().run()}
        label="箇条書き"
      >•</ToolButton>
      <ToolButton
        active={editor.isActive('orderedList')}
        onClick={() => editor.chain().focus().toggleOrderedList().run()}
        label="番号付きリスト"
      >1.</ToolButton>
      <ToolButton onClick={addLink} label="リンクpenambahan" active={editor.isActive('link')}>🔗</ToolButton>
      <ToolButton onClick={addImage} label="gambarpenambahan">📷</ToolButton>
    </div>
  );
}

function ToolButton({ active, onClick, label, children }: {
  active?: boolean; onClick: () => void; label: string; children: React.ReactNode;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      aria-label={label}
      aria-pressed={active}
      className={`px-3 py-1 rounded text-sm font-medium ${
        active ? 'bg-blue-100 text-blue-700' : 'hover:bg-gray-200'
      }`}
    >{children}</button>
  );
}

pembuatan カスタムエクステンション

> メンション機能(@pengguna名) エクステンション buatkan.
import { Node, mergeAttributes } from '@tiptap/core';
import Suggestion from '@tiptap/suggestion';

const Mention = Node.create({
  name: 'mention',
  group: 'inline',
  inline: true,
  selectable: false,
  atom: true,

  addAttributes() {
    return {
      id: { default: null },
      label: { default: null },
    };
  },

  parseHTML() {
    return [{ tag: 'span[data-mention]' }];
  },

  renderHTML({ node, HTMLAttributes }) {
    return ['span', mergeAttributes(HTMLAttributes, {
      'data-mention': '',
      class: 'mention bg-blue-100 text-blue-700 rounded px-1',
    }), `@${node.attrs.label}`];
  },

  addProseMirrorPlugins() {
    return [
      Suggestion({
        editor: this.editor,
        char: '@',
        items: ({ query }) => fetchUsers(query),
        render: () => createSuggestionRenderer(),
      }),
    ];
  },
});

サニタイズ konten

import DOMPurify from 'dompurify';

function sanitizeContent(html: string): string {
  return DOMPurify.sanitize(html, {
    ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'ul', 'ol', 'li', 'a', 'img', 'h1', 'h2', 'h3', 'blockquote', 'code', 'pre'],
    ALLOWED_ATTR: ['href', 'src', 'alt', 'class', 'target', 'rel'],
  });
}

Summary

Untuk Claude Codeを使えば、Tiptapをベースとしたリッチテキストeditorのpembangunanから、カスタムエクステンションpengembangan、セキュアなkontenmanajemenまでefisienにimplementasiできます。form設計についてはformvalidasiを、マークダウンpemrosesan, lihat Markdown処理の記事.

Tiptap 詳細 Tiptap公式dokumen silakan lihat.

#Claude Code #リッチテキストeditor #React #Tiptap #kontenmanajemen

Tingkatkan alur kerja Claude Code kamu

50 template prompt yang sudah teruji, siap copy-paste ke Claude Code sekarang juga.

Gratis

PDF Gratis: Cheatsheet Claude Code dalam 5 Menit

Perintah penting, pintasan, dan contoh prompt dalam satu halaman siap cetak.

Unduh PDF
M

Tentang Penulis

Masa

Engineer yang aktif menggunakan Claude Code. Mengelola claudecode-lab.com, media teknologi 10 bahasa dengan lebih dari 2.000 halaman.