Tips & Tricks

Claude Code के साथ Build a Rich Text Editor कैसे करें

Claude Code का उपयोग करके build a rich text editor सीखें। Practical code examples और step-by-step guidance शामिल है।

リッチテキストエディタのbuild

リッチテキストエディタはCMS、メールcreate、ドキュメントEdit आदि多くのアプリでज़रूरीとされますが、一 सेbuildするのは非常にcomplex है।Claude Code का उपयोग करके、Tiptap आदिのlibraryをベースに、用途に合ったエディタを素早くcustomizeでき है।

Tiptapベースのエディタbuild

> Tiptapを使ったリッチテキストエディタを作って。
> 太字、イタリック、list、link、画像挿入に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>
  );
}

ツールバーのimplementation

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

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

  const addImage = () => {
    const url = window.prompt('画像URLを入力');
    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="書式settings">
      <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="番号付きlist"
      >1.</ToolButton>
      <ToolButton onClick={addLink} label="linkadd" active={editor.isActive('link')}>🔗</ToolButton>
      <ToolButton onClick={addImage} label="画像add">📷</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>
  );
}

カスタムエクステンションのcreate

> メンションfeatures(@user名)のエクステンションを作って。
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(),
      }),
    ];
  },
});

コンテンツのサニタイズ

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

Claude Code का उपयोग करके、Tiptapをベースとしたリッチテキストエディタのbuild से、カスタムエクステンションdevelopment、セキュアなコンテンツmanagement तकefficientlyimplementationでき है।form設計के बारे मेंはformvalidationを、マークダウンprocessingはMarkdownprocessingの記事をदेखें。

Tiptapके details के लिएTiptapofficial documentationदेखें。

#Claude Code #リッチテキストエディタ #React #Tiptap #コンテンツmanagement
मुफ़्त

मुफ़्त PDF: 5 मिनट में Claude Code चीटशीट

बस अपना ईमेल दर्ज करें और हम तुरंत A4 एक-पृष्ठ चीटशीट PDF भेज देंगे।

हम आपकी व्यक्तिगत जानकारी की सुरक्षा करते हैं और स्पैम नहीं भेजते।

Masa

लेखक के बारे में

Masa

Claude Code का गहराई से उपयोग करने वाले इंजीनियर। claudecode-lab.com चलाते हैं, जो 10 भाषाओं में 2,000 से अधिक पेजों वाला टेक मीडिया है।