- vừa được xem lúc

Xây dựng trình soạn thảo văn bản RichText mạnh mẽ với TipTap và React (kèm tính năng Mentions)

0 0 1

Người đăng: Vinh Phạm

Theo Viblo Asia

Bạn muốn ứng dụng React của mình sở hữu một trình soạn thảo RichText vừa mạnh mẽ vừa dễ tùy chỉnh? TipTap chính là lựa chọn tuyệt vời dành cho bạn. Hãy cùng tìm hiểu cách tích hợp TipTap, thêm tính năng mentions, và xử lý một số vấn đề phát sinh thường gặp khi xây dựng trình soạn thảo này.

Bước 1: Cài đặt các phụ thuộc

Trước khi bắt đầu, hãy cài đặt các thư viện cần thiết:

npm install @tiptap/react @tiptap/starter-kit @tiptap/extension-mention

Bước 2: Tạo một trình soạn thảo RichText cơ bản

Bắt đầu bằng cách tạo một thành phần RichTextEditor. Sau đây là một triển khai đơn giản:

import { useEditor, EditorContent } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; export const RichTextEditor = ({ content, onChange }) => { const editor = useEditor({ extensions: [StarterKit], content: content, onUpdate: ({ editor }) => { onChange(editor.getHTML()); }, }); return <EditorContent editor={editor} />; };

Bước 3: Thêm Mention

Tính năng mentions giúp tăng cường tương tác người dùng, đặc biệt trong các ứng dụng chat hoặc cộng tác. Để thêm mentions, chúng ta cần cài đặt và cấu hình Mention extension từ @tiptap/extension-mention.

import Mention from '@tiptap/extension-mention'; export const RichTextEditor = ({ content, onChange, mentions }) => { const editor = useEditor({ extensions: [ StarterKit, Mention.configure({ HTMLAttributes: { class: 'mention' }, suggestion: { items: ({ query }) => mentions.filter(item => item.display.toLowerCase().includes(query.toLowerCase())).slice(0, 5), render: () => { let component; let popup; return { onStart: (props) => { popup = document.createElement('div'); popup.className = 'mention-popup'; document.body.appendChild(popup); component = { updateProps: () => { popup.innerHTML = ` <div class="items"> ${props.items.map(item => ` <button class="item ${item.selected ? 'is-selected' : ''}">${item.display}</button> `).join('')} </div> `; }, destroy: () => popup.remove(), }; popup.addEventListener('click', (e) => { const button = e.target.closest('button'); if (button) { const index = Array.from(popup.querySelectorAll('.item')).indexOf(button); props.command({ id: props.items[index].id, label: props.items[index].display }); } }); component.updateProps(); }, onExit: () => component?.destroy(), }; }, }, }), ], content, onUpdate: ({ editor }) => onChange(editor.getHTML()), }); return <EditorContent editor={editor} />; };

Bước 4: Định dạng Popup Mention

Các mentions phải khác biệt về mặt hình ảnh. Thêm các kiểu sau để tăng khả năng sử dụng:

.mention-popup { background: white; border-radius: 8px; box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.1); padding: 8px; position: absolute; z-index: 1000; } .mention-popup .items { display: flex; flex-direction: column; } .mention-popup .item { padding: 8px; cursor: pointer; border-radius: 4px; } .mention-popup .item:hover, .mention-popup .item.is-selected { background: #f0f0f0; }

Bước 5: Các trường hợp ngoại lệ sẽ gặp phải trong quá trình triển khai

1. Con trỏ nhảy: Để tránh con trỏ nhảy khi đang gõ, hãy đảm bảo các bản cập nhật nội dung giữ nguyên vị trí của con trỏ:

const editor = useEditor({ extensions: [StarterKit], content, onUpdate: ({ editor }) => { const selection = editor.state.selection; onChange(editor.getHTML()); editor.commands.setTextSelection(selection); }, });

2. Không hiển thị Placeholder: Sử dụng tiện ích mở rộng Placeholder để hiển thị gợi ý khi trình soạn thảo trống:

import Placeholder from '@tiptap/extension-placeholder'; const editor = useEditor({ extensions: [ StarterKit, Placeholder.configure({ placeholder: 'Type something...' }), ], });

Cuối cùng, nếu danh sách gợi ý mention không hiển thị, hãy kiểm tra lại phương thức suggestion.items để đảm bảo nó lọc và trả về danh sách đúng như mong đợi.

Bước 6: Tích hợp vào ứng dụng của bạn

Để tích hợp trình soạn thảo vào ứng dụng, bạn có thể đặt nó trong một modal hoặc form component, ví dụ như form tạo thông báo. Form này sẽ chứa component RichTextEditor, nhận nội dung từ editor và gửi đi khi người dùng submit.

import React from 'react'; const NotificationForm = ({ mentions, onSubmit }) => { const [content, setContent] = React.useState(''); return ( <form onSubmit={() => onSubmit(content)}> <RichTextEditor content={content} onChange={setContent} mentions={mentions} /> <button type="submit">Send</button> </form> ); };

Kết luận

Với TipTap, việc xây dựng trình soạn thảo RichText mạnh mẽ và thân thiện với người dùng trở nên dễ dàng hơn bao giờ hết. Tính năng mentions giúp tăng cường tính tương tác, làm cho ứng dụng của bạn hấp dẫn hơn đối với người dùng. Để tìm hiểu thêm, hãy truy cập trang web chính thức của TipTap.

Bình luận

Bài viết tương tự

- vừa được xem lúc

The Twelve-Factor App, cẩm nang gối đầu giường trong xây dựng application (Phần 1)

Giới thiệu. Ngày nay các phần mềm được triển khai dưới dạng các dịch vụ, chúng được gọi là các web apps hay software-as-a-service (SaaS).

0 0 29

- vừa được xem lúc

8 Sai lầm phổ biến khi lập trình Android

1. Hard code.

0 0 185

- vừa được xem lúc

Popular interview question: What is the difference between Process and Thread? 10 seconds a day

Video được đăng tại channel Tips Javascript

0 0 28

- vừa được xem lúc

Thuật toán và ứng dụng - P1

Mục đích series. . Những bài toán gắn liền với thực tế. Từ đó thấy được tầm quan trọng của thuật toán trong lập trình.

0 0 35

- vừa được xem lúc

Tác dụng của Docker trong quá trình học tập

Docker bây giờ gần như là kiến thức bắt buộc đối với các anh em Dev và Devops, nhưng mà đối với sinh viên IT nói chung vẫn còn khá mơ hồ và không biết tác dụng thực tế của nó. Hôm nay mình sẽ chia sẻ

0 0 30

- vừa được xem lúc

Làm giàu trong ngành IT

Hầu như mọi người đều đi làm để kiếm tiền, ít người đi làm vì thấy cái nghề đó thú vị lắm. Bây giờ vất cho mình 100 tỷ bảo mình bỏ nghề thì mình cũng bỏ thôi.

0 0 32