Files
afrov2/admin/src/components/RichTextEditor.tsx
2026-04-22 22:59:12 +02:00

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>
);
}