diff --git a/apps/app/components/issues/description-form.tsx b/apps/app/components/issues/description-form.tsx index e81c8c1b3..fb7d574ee 100644 --- a/apps/app/components/issues/description-form.tsx +++ b/apps/app/components/issues/description-form.tsx @@ -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: () => ( - - - - ), -}); +// const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), { +// ssr: false, +// loading: () => ( +// +// +// +// ), +// }); + +import Tiptap from "./tiptap"; // types import { IIssue } from "types"; @@ -106,9 +108,8 @@ export const IssueDescriptionForm: FC = ({ {characterLimit && (
255 ? "text-red-500" : "" - }`} + className={`${watch("name").length === 0 || watch("name").length > 255 ? "text-red-500" : "" + }`} > {watch("name").length} @@ -125,31 +126,39 @@ export const IssueDescriptionForm: FC = ({ if (!value && !watch("description_html")) return <>; return ( - { - 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 + } /> + // { + // 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} + // /> ); }} /> diff --git a/apps/app/components/issues/form.tsx b/apps/app/components/issues/form.tsx index e6fc11ae2..e16bd317f 100644 --- a/apps/app/components/issues/form.tsx +++ b/apps/app/components/issues/form.tsx @@ -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: () => ( - - - - ), -}); +// const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), { +// ssr: false, +// loading: () => ( +// +// +// +// ), +// }); -import { IRemirrorRichTextEditor } from "components/rich-text-editor"; +// import { IRemirrorRichTextEditor } from "components/rich-text-editor"; -const WrappedRemirrorRichTextEditor = React.forwardRef< - IRemirrorRichTextEditor, - IRemirrorRichTextEditor ->((props, ref) => ); - -WrappedRemirrorRichTextEditor.displayName = "WrappedRemirrorRichTextEditor"; +// const WrappedRemirrorRichTextEditor = React.forwardRef< +// IRemirrorRichTextEditor, +// IRemirrorRichTextEditor +// >((props, ref) => ); +// +// WrappedRemirrorRichTextEditor.displayName = "WrappedRemirrorRichTextEditor"; const defaultValues: Partial = { project: "", @@ -362,23 +362,23 @@ export const IssueForm: FC = ({ AI
- ( - setValue("description", jsonValue)} - onHTMLChange={(htmlValue) => setValue("description_html", htmlValue)} - placeholder="Description" - ref={editorRef} - /> - )} - /> + {/* ( */} + {/* setValue("description", jsonValue)} */} + {/* onHTMLChange={(htmlValue) => setValue("description_html", htmlValue)} */} + {/* placeholder="Description" */} + {/* ref={editorRef} */} + {/* /> */} + {/* )} */} + {/* /> */} { diff --git a/apps/app/components/issues/props.tsx b/apps/app/components/issues/props.tsx new file mode 100644 index 000000000..54306429c --- /dev/null +++ b/apps/app/components/issues/props.tsx @@ -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`, + } +}; diff --git a/apps/app/components/issues/tiptap.tsx b/apps/app/components/issues/tiptap.tsx new file mode 100644 index 000000000..d3f554d4c --- /dev/null +++ b/apps/app/components/issues/tiptap.tsx @@ -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 ( +
{ + editor?.chain().focus().run(); + }} + className={`tiptap-editor-container relative min-h-[150px] ${editorClassNames}`} + > + +
+ ); +}; + +export default Tiptap; diff --git a/apps/app/styles/editor.css b/apps/app/styles/editor.css index ea4b2e601..293a017b2 100644 --- a/apps/app/styles/editor.css +++ b/apps/app/styles/editor.css @@ -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;