2023-11-08 12:30:53 +00:00
|
|
|
"use client";
|
|
|
|
import * as React from "react";
|
|
|
|
import {
|
|
|
|
EditorContainer,
|
|
|
|
EditorContentWrapper,
|
|
|
|
getEditorClassNames,
|
|
|
|
useEditor,
|
|
|
|
} from "@plane/editor-core";
|
|
|
|
import { EditorBubbleMenu } from "./menus/bubble-menu";
|
|
|
|
import { RichTextEditorExtensions } from "./extensions";
|
2023-11-28 06:04:20 +00:00
|
|
|
import {
|
|
|
|
DeleteImage,
|
|
|
|
IMentionSuggestion,
|
|
|
|
RestoreImage,
|
|
|
|
UploadImage,
|
|
|
|
} from "@plane/editor-types";
|
2023-10-13 06:35:49 +00:00
|
|
|
|
2023-11-28 06:04:20 +00:00
|
|
|
export type IRichTextEditor = {
|
2023-10-13 06:35:49 +00:00
|
|
|
value: string;
|
2023-11-17 06:59:30 +00:00
|
|
|
dragDropEnabled?: boolean;
|
2023-10-13 06:35:49 +00:00
|
|
|
uploadFile: UploadImage;
|
2023-11-28 06:04:20 +00:00
|
|
|
restoreFile: RestoreImage;
|
2023-10-13 06:35:49 +00:00
|
|
|
deleteFile: DeleteImage;
|
|
|
|
noBorder?: boolean;
|
|
|
|
borderOnFocus?: boolean;
|
2023-11-08 12:30:53 +00:00
|
|
|
cancelUploadImage?: () => any;
|
2023-12-07 06:34:21 +00:00
|
|
|
rerenderOnPropsChange?: {
|
|
|
|
id: string;
|
|
|
|
description_html: string;
|
|
|
|
};
|
2023-10-13 06:35:49 +00:00
|
|
|
customClassName?: string;
|
|
|
|
editorContentCustomClassNames?: string;
|
|
|
|
onChange?: (json: any, html: string) => void;
|
2023-11-08 12:30:53 +00:00
|
|
|
setIsSubmitting?: (
|
|
|
|
isSubmitting: "submitting" | "submitted" | "saved",
|
|
|
|
) => void;
|
2023-10-13 06:35:49 +00:00
|
|
|
setShouldShowAlert?: (showAlert: boolean) => void;
|
|
|
|
forwardedRef?: any;
|
|
|
|
debouncedUpdatesEnabled?: boolean;
|
2023-11-01 11:06:37 +00:00
|
|
|
mentionHighlights?: string[];
|
|
|
|
mentionSuggestions?: IMentionSuggestion[];
|
2023-11-28 06:04:20 +00:00
|
|
|
};
|
2023-10-13 06:35:49 +00:00
|
|
|
|
2023-11-28 06:04:20 +00:00
|
|
|
export interface RichTextEditorProps extends IRichTextEditor {
|
2023-10-13 06:35:49 +00:00
|
|
|
forwardedRef?: React.Ref<EditorHandle>;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface EditorHandle {
|
|
|
|
clearEditor: () => void;
|
|
|
|
setEditorValue: (content: string) => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
const RichTextEditor = ({
|
|
|
|
onChange,
|
2023-11-17 06:59:30 +00:00
|
|
|
dragDropEnabled,
|
2023-10-13 06:35:49 +00:00
|
|
|
debouncedUpdatesEnabled,
|
|
|
|
setIsSubmitting,
|
|
|
|
setShouldShowAlert,
|
|
|
|
editorContentCustomClassNames,
|
|
|
|
value,
|
|
|
|
uploadFile,
|
|
|
|
deleteFile,
|
|
|
|
noBorder,
|
2023-11-08 12:30:53 +00:00
|
|
|
cancelUploadImage,
|
2023-10-13 06:35:49 +00:00
|
|
|
borderOnFocus,
|
|
|
|
customClassName,
|
2023-11-28 06:04:20 +00:00
|
|
|
restoreFile,
|
2023-10-13 06:35:49 +00:00
|
|
|
forwardedRef,
|
2023-11-01 11:06:37 +00:00
|
|
|
mentionHighlights,
|
2023-12-07 06:34:21 +00:00
|
|
|
rerenderOnPropsChange,
|
2023-11-08 12:30:53 +00:00
|
|
|
mentionSuggestions,
|
2023-10-13 06:35:49 +00:00
|
|
|
}: RichTextEditorProps) => {
|
|
|
|
const editor = useEditor({
|
|
|
|
onChange,
|
|
|
|
debouncedUpdatesEnabled,
|
|
|
|
setIsSubmitting,
|
|
|
|
setShouldShowAlert,
|
|
|
|
value,
|
|
|
|
uploadFile,
|
2023-11-08 12:30:53 +00:00
|
|
|
cancelUploadImage,
|
2023-10-13 06:35:49 +00:00
|
|
|
deleteFile,
|
2023-11-28 06:04:20 +00:00
|
|
|
restoreFile,
|
2023-10-13 06:35:49 +00:00
|
|
|
forwardedRef,
|
2023-12-07 06:34:21 +00:00
|
|
|
rerenderOnPropsChange,
|
2023-11-17 06:59:30 +00:00
|
|
|
extensions: RichTextEditorExtensions(
|
|
|
|
uploadFile,
|
|
|
|
setIsSubmitting,
|
|
|
|
dragDropEnabled,
|
|
|
|
),
|
2023-11-01 11:06:37 +00:00
|
|
|
mentionHighlights,
|
2023-11-08 12:30:53 +00:00
|
|
|
mentionSuggestions,
|
2023-10-13 06:35:49 +00:00
|
|
|
});
|
|
|
|
|
2023-11-08 12:30:53 +00:00
|
|
|
const editorClassNames = getEditorClassNames({
|
|
|
|
noBorder,
|
|
|
|
borderOnFocus,
|
|
|
|
customClassName,
|
|
|
|
});
|
2023-10-13 06:35:49 +00:00
|
|
|
|
|
|
|
if (!editor) return null;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<EditorContainer editor={editor} editorClassNames={editorClassNames}>
|
|
|
|
{editor && <EditorBubbleMenu editor={editor} />}
|
|
|
|
<div className="flex flex-col">
|
2023-11-08 12:30:53 +00:00
|
|
|
<EditorContentWrapper
|
|
|
|
editor={editor}
|
|
|
|
editorContentCustomClassNames={editorContentCustomClassNames}
|
|
|
|
/>
|
2023-10-13 06:35:49 +00:00
|
|
|
</div>
|
2023-11-08 12:30:53 +00:00
|
|
|
</EditorContainer>
|
2023-10-13 06:35:49 +00:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2023-11-08 12:30:53 +00:00
|
|
|
const RichTextEditorWithRef = React.forwardRef<EditorHandle, IRichTextEditor>(
|
|
|
|
(props, ref) => <RichTextEditor {...props} forwardedRef={ref} />,
|
|
|
|
);
|
2023-10-13 06:35:49 +00:00
|
|
|
|
|
|
|
RichTextEditorWithRef.displayName = "RichTextEditorWithRef";
|
|
|
|
|
2023-11-08 12:30:53 +00:00
|
|
|
export { RichTextEditor, RichTextEditorWithRef };
|