79 lines
2.0 KiB
TypeScript
79 lines
2.0 KiB
TypeScript
"use client";
|
|
|
|
import React, { useMemo, useRef } from 'react';
|
|
import dynamic from 'next/dynamic';
|
|
import 'react-quill-new/dist/quill.snow.css';
|
|
|
|
// We need to import Quill for registration
|
|
const ReactQuill = dynamic(async () => {
|
|
const { default: RQ, Quill } = await import("react-quill-new");
|
|
|
|
// Register custom Divider Blot
|
|
if (Quill) {
|
|
const BlockEmbed = Quill.import('blots/block/embed') as any;
|
|
class DividerBlot extends BlockEmbed {
|
|
static blotName = 'divider';
|
|
static tagName = 'hr';
|
|
}
|
|
Quill.register(DividerBlot);
|
|
}
|
|
|
|
return RQ;
|
|
}, {
|
|
ssr: false,
|
|
loading: () => <div className="h-64 w-full bg-slate-900 animate-pulse rounded-lg border border-slate-700" />
|
|
}) as any;
|
|
|
|
interface RichTextEditorProps {
|
|
value: string;
|
|
onChange: (content: string) => void;
|
|
placeholder?: string;
|
|
}
|
|
|
|
export default function RichTextEditor({ value, onChange, placeholder }: RichTextEditorProps) {
|
|
const quillRef = useRef<any>(null);
|
|
|
|
const modules = useMemo(() => ({
|
|
toolbar: {
|
|
container: [
|
|
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
|
|
['bold', 'italic', 'underline', 'strike'],
|
|
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
|
|
['divider', 'link', 'clean'],
|
|
],
|
|
handlers: {
|
|
divider: function() {
|
|
const quill = (quillRef.current as any)?.getEditor();
|
|
if (quill) {
|
|
const range = quill.getSelection(true);
|
|
quill.insertEmbed(range.index, 'divider', true);
|
|
quill.setSelection(range.index + 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}), []);
|
|
|
|
const formats = [
|
|
'header',
|
|
'bold', 'italic', 'underline', 'strike',
|
|
'list',
|
|
'divider', 'link',
|
|
];
|
|
|
|
return (
|
|
<div className="quill-dark-wrapper">
|
|
<ReactQuill
|
|
ref={quillRef}
|
|
theme="snow"
|
|
value={value}
|
|
onChange={onChange}
|
|
modules={modules}
|
|
formats={formats}
|
|
placeholder={placeholder}
|
|
className="bg-slate-900 text-white rounded-lg overflow-hidden border border-slate-700 min-h-[300px]"
|
|
/>
|
|
</div>
|
|
);
|
|
}
|