Giới thiệu
Bạn đang tìm kiếm một giải pháp để phát triển một trình soạn thảo RichText tích hợp trong ứng dụng React của mình? TipTap là một thư viện tuyệt vời, dễ dàng tùy chỉnh và mạnh mẽ, giúp bạn xây dựng trình soạn thảo văn bản hoàn hảo. Bài viết này sẽ hướng dẫn bạn từng bước để tích hợp TipTap, thêm tính năng mentions, và khắc phục một số vấn đề thường gặp trong quá trình phát triển.
Bước 1: Cài Đặt Các Thư Viện Cần Thiết
Trước tiên, bạn cần cài đặt các thư viện cần thiết cho TipTap:
bash
npm install @tiptap/react @tiptap/starter-kit @tiptap/extension-mention
Bước 2: Tạo Trình Soạn Thảo RichText Cơ Bản
Chúng ta sẽ bắt đầu bằng cách tạo một thành phần RichTextEditor. Dưới đây là một ví dụ đơn giản để thực hiện điều này:
javascript
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 Tính Năng Mention
Tính năng mentions giúp tăng cường sự tương tác của người dùng. Để thêm tính năng này, chúng ta sẽ cài đặt và cấu hình Mention extension từ @tiptap/extension-mention.
javascript
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 Cho Tính Năng Mention
Để tăng cường khả năng sử dụng và tính trực quan của mentions, bạn có thể thêm các kiểu sau:
css
.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: Khắc Phục Một Số Vấn Đề Thường Gặp
1. Vấn Đề Với Con Trỏ Nhảy
Đối với vấn đề con trỏ nhảy khi gõ, hãy giữ nguyên vị trí con trỏ bằng cách cập nhật nội dung như sau:
javascript
const editor = useEditor({
extensions: [StarterKit],
content,
onUpdate: ({ editor }) => {
const selection = editor.state.selection;
onChange(editor.getHTML());
editor.commands.setTextSelection(selection);
},
});
2. Thiếu Hiện Placeholder
Nếu placeholder không hiển thị, hãy sử dụng tiện ích mở rộng Placeholder:
javascript
import Placeholder from '@tiptap/extension-placeholder';
const editor = useEditor({
extensions: [
StarterKit,
Placeholder.configure({ placeholder: 'Hãy nhập nội dung ở đây...' }),
],
});
3. Danh Sách Gợi Ý Mention Không Hiển Thị
Kiểm tra lại phương thức suggestion.items để đảm bảo lọc và trả về danh sách hợp lệ.
Bước 6: Tích Hợp Vào Ứng Dụng Của Bạn
Cuối cùng, để tích hợp trình soạn thảo vào ứng dụng, bạn có thể sử dụng RichTextEditor trong một form. Ví dụ:
javascript
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">Gửi</button>
</form>
);
};
Kết Luận
Với TipTap, việc xây dựng một trình soạn thảo RichText chuyên nghiệp và thân thiện với người dùng thật sự đơn giản và nhanh chóng. Tính năng mentions không chỉ tăng cường khả năng tương tác mà còn làm cho ứng dụng của bạn trở nên sinh động và hấp dẫn hơn. Để có thêm thông tin chi tiết, hãy truy cập vào trang web chính thức của TipTap.
source: viblo