mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
styles migrated for remirror to tiptap transition
This commit is contained in:
parent
dd5ff737d1
commit
d62ac268c6
@ -8,14 +8,16 @@ import { Controller, useForm } from "react-hook-form";
|
||||
import useReloadConfirmations from "hooks/use-reload-confirmation";
|
||||
// components
|
||||
import { Loader, TextArea } from "components/ui";
|
||||
const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), {
|
||||
ssr: false,
|
||||
loading: () => (
|
||||
<Loader>
|
||||
<Loader.Item height="12rem" width="100%" />
|
||||
</Loader>
|
||||
),
|
||||
});
|
||||
// const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), {
|
||||
// ssr: false,
|
||||
// loading: () => (
|
||||
// <Loader>
|
||||
// <Loader.Item height="12rem" width="100%" />
|
||||
// </Loader>
|
||||
// ),
|
||||
// });
|
||||
|
||||
import Tiptap from "./tiptap";
|
||||
// types
|
||||
import { IIssue } from "types";
|
||||
|
||||
@ -106,9 +108,8 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = ({
|
||||
{characterLimit && (
|
||||
<div className="pointer-events-none absolute bottom-1 right-1 z-[2] rounded bg-custom-background-100 text-custom-text-200 p-0.5 text-xs">
|
||||
<span
|
||||
className={`${
|
||||
watch("name").length === 0 || watch("name").length > 255 ? "text-red-500" : ""
|
||||
}`}
|
||||
className={`${watch("name").length === 0 || watch("name").length > 255 ? "text-red-500" : ""
|
||||
}`}
|
||||
>
|
||||
{watch("name").length}
|
||||
</span>
|
||||
@ -125,31 +126,39 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = ({
|
||||
if (!value && !watch("description_html")) return <></>;
|
||||
|
||||
return (
|
||||
<RemirrorRichTextEditor
|
||||
value={
|
||||
!value ||
|
||||
<Tiptap value={
|
||||
!value ||
|
||||
value === "" ||
|
||||
(typeof value === "object" && Object.keys(value).length === 0)
|
||||
? watch("description_html")
|
||||
: value
|
||||
}
|
||||
onJSONChange={(jsonValue) => {
|
||||
setShowAlert(true);
|
||||
setValue("description", jsonValue);
|
||||
}}
|
||||
onHTMLChange={(htmlValue) => {
|
||||
setShowAlert(true);
|
||||
setValue("description_html", htmlValue);
|
||||
}}
|
||||
onBlur={() => {
|
||||
setIsSubmitting(true);
|
||||
handleSubmit(handleDescriptionFormSubmit)()
|
||||
.then(() => setShowAlert(false))
|
||||
.finally(() => setIsSubmitting(false));
|
||||
}}
|
||||
placeholder="Description"
|
||||
editable={isAllowed}
|
||||
? watch("description_html")
|
||||
: value
|
||||
}
|
||||
/>
|
||||
// <RemirrorRichTextEditor
|
||||
// value = {
|
||||
// !value ||
|
||||
// value === "" ||
|
||||
// (typeof value === "object" && Object.keys(value).length === 0)
|
||||
// ? watch("description_html")
|
||||
// : value
|
||||
// }
|
||||
// onJSONChange={(jsonValue) => {
|
||||
// setShowAlert(true);
|
||||
// setValue("description", jsonValue);
|
||||
// }}
|
||||
// onHTMLChange={(htmlValue) => {
|
||||
// setShowAlert(true);
|
||||
// setValue("description_html", htmlValue);
|
||||
// }}
|
||||
// onBlur={() => {
|
||||
// setIsSubmitting(true);
|
||||
// handleSubmit(handleDescriptionFormSubmit)()
|
||||
// .then(() => setShowAlert(false))
|
||||
// .finally(() => setIsSubmitting(false));
|
||||
// }}
|
||||
// placeholder="Description"
|
||||
// editable={isAllowed}
|
||||
// />
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
@ -37,23 +37,23 @@ import { SparklesIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
import type { ICurrentUserResponse, IIssue, ISearchIssueResponse } from "types";
|
||||
// rich-text-editor
|
||||
const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), {
|
||||
ssr: false,
|
||||
loading: () => (
|
||||
<Loader className="mt-4">
|
||||
<Loader.Item height="12rem" width="100%" />
|
||||
</Loader>
|
||||
),
|
||||
});
|
||||
// const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), {
|
||||
// ssr: false,
|
||||
// loading: () => (
|
||||
// <Loader className="mt-4">
|
||||
// <Loader.Item height="12rem" width="100%" />
|
||||
// </Loader>
|
||||
// ),
|
||||
// });
|
||||
|
||||
import { IRemirrorRichTextEditor } from "components/rich-text-editor";
|
||||
// import { IRemirrorRichTextEditor } from "components/rich-text-editor";
|
||||
|
||||
const WrappedRemirrorRichTextEditor = React.forwardRef<
|
||||
IRemirrorRichTextEditor,
|
||||
IRemirrorRichTextEditor
|
||||
>((props, ref) => <RemirrorRichTextEditor {...props} forwardedRef={ref} />);
|
||||
|
||||
WrappedRemirrorRichTextEditor.displayName = "WrappedRemirrorRichTextEditor";
|
||||
// const WrappedRemirrorRichTextEditor = React.forwardRef<
|
||||
// IRemirrorRichTextEditor,
|
||||
// IRemirrorRichTextEditor
|
||||
// >((props, ref) => <RemirrorRichTextEditor {...props} forwardedRef={ref} />);
|
||||
//
|
||||
// WrappedRemirrorRichTextEditor.displayName = "WrappedRemirrorRichTextEditor";
|
||||
|
||||
const defaultValues: Partial<IIssue> = {
|
||||
project: "",
|
||||
@ -362,23 +362,23 @@ export const IssueForm: FC<IssueFormProps> = ({
|
||||
AI
|
||||
</button>
|
||||
</div>
|
||||
<Controller
|
||||
name="description"
|
||||
control={control}
|
||||
render={({ field: { value } }) => (
|
||||
<WrappedRemirrorRichTextEditor
|
||||
value={
|
||||
!value || (typeof value === "object" && Object.keys(value).length === 0)
|
||||
? watch("description_html")
|
||||
: value
|
||||
}
|
||||
onJSONChange={(jsonValue) => setValue("description", jsonValue)}
|
||||
onHTMLChange={(htmlValue) => setValue("description_html", htmlValue)}
|
||||
placeholder="Description"
|
||||
ref={editorRef}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* <Controller */}
|
||||
{/* name="description" */}
|
||||
{/* control={control} */}
|
||||
{/* render={({ field: { value } }) => ( */}
|
||||
{/* <WrappedRemirrorRichTextEditor */}
|
||||
{/* value={ */}
|
||||
{/* !value || (typeof value === "object" && Object.keys(value).length === 0) */}
|
||||
{/* ? watch("description_html") */}
|
||||
{/* : value */}
|
||||
{/* } */}
|
||||
{/* onJSONChange={(jsonValue) => setValue("description", jsonValue)} */}
|
||||
{/* onHTMLChange={(htmlValue) => setValue("description_html", htmlValue)} */}
|
||||
{/* placeholder="Description" */}
|
||||
{/* ref={editorRef} */}
|
||||
{/* /> */}
|
||||
{/* )} */}
|
||||
{/* /> */}
|
||||
<GptAssistantModal
|
||||
isOpen={gptAssistantModal}
|
||||
handleClose={() => {
|
||||
|
7
apps/app/components/issues/props.tsx
Normal file
7
apps/app/components/issues/props.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import { EditorProps } from "@tiptap/pm/view";
|
||||
|
||||
export const TiptapEditorProps: EditorProps = {
|
||||
attributes: {
|
||||
class: `prose prose-brand max-w-full prose-headings:font-display font-default focus:outline-none`,
|
||||
}
|
||||
};
|
43
apps/app/components/issues/tiptap.tsx
Normal file
43
apps/app/components/issues/tiptap.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import Placeholder from '@tiptap/extension-placeholder';
|
||||
import { useEditor, EditorContent } from '@tiptap/react';
|
||||
import StarterKit from '@tiptap/starter-kit';
|
||||
import { EditorBubbleMenu } from './EditorBubbleMenu';
|
||||
import { TiptapEditorProps } from "./props";
|
||||
|
||||
type TiptapProps = {
|
||||
value: string;
|
||||
noBorder?: boolean;
|
||||
borderOnFocus?: boolean;
|
||||
customClassName?: string;
|
||||
}
|
||||
|
||||
const Tiptap = ({ value, noBorder, borderOnFocus, customClassName }: TiptapProps) => {
|
||||
const editor = useEditor({
|
||||
editorProps: TiptapEditorProps,
|
||||
extensions: [
|
||||
StarterKit,
|
||||
Placeholder.configure({
|
||||
placeholder: 'Description...',
|
||||
})
|
||||
],
|
||||
content: value,
|
||||
});
|
||||
|
||||
const editorClassNames = `mt-2 p-3 relative focus:outline-none rounded-md focus:border-custom-border-200
|
||||
${noBorder ? '' : 'border border-custom-border-200'
|
||||
} ${borderOnFocus ? 'focus:border border-custom-border-200' : 'focus:border-0'
|
||||
} ${customClassName}`;
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={() => {
|
||||
editor?.chain().focus().run();
|
||||
}}
|
||||
className={`tiptap-editor-container relative min-h-[150px] ${editorClassNames}`}
|
||||
>
|
||||
<EditorContent editor={editor} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tiptap;
|
@ -8,6 +8,14 @@
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.ProseMirror p.is-editor-empty:first-child::before {
|
||||
color: rgb(var(--color-text-400));
|
||||
content: attr(data-placeholder);
|
||||
float: left;
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ProseMirror {
|
||||
position: relative;
|
||||
word-wrap: break-word;
|
||||
|
Loading…
Reference in New Issue
Block a user