Skip to content

Commit

Permalink
refactor: enable bubble menu for text editor in task detail (#166)
Browse files Browse the repository at this point in the history
  • Loading branch information
hudy9x authored Apr 27, 2024
1 parent ae40e94 commit cb7b4de
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { BubbleMenu, Editor } from "@tiptap/react";
import { LuBold, LuItalic, LuStrikethrough, LuList, LuListOrdered, LuHeading1, LuHeading2, LuHeading3, LuCode2, LuCornerUpLeft, LuImage } from "react-icons/lu";
import Tooltip from "../../Tooltip";
import { useCallback } from "react";

export default function BubbleEditorMenu({ editor }: { editor: Editor }) {
const getClasses = (isActive: boolean) => {
const classes = []

classes.push('bubble-action-btn')

isActive && classes.push('is-active')
return classes.join(' ')
}


const setImage = useCallback(() => {
const url = window.prompt('Image url:')
if (url) {
editor.chain().focus().setImage({ src: url }).run()
}

}, [editor])

return <BubbleMenu editor={editor} tippyOptions={{ duration: 100 }}>
<div className='flex gap-1 border border-gray-300 bg-white dark:bg-gray-800 shadow-lg dark:shadow-gray-900 rounded-md dark:border-gray-700 dark:bg-gray-900 p-1'>
<span
onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
className={getClasses(editor.isActive('heading', { level: 1 }))}
>
<LuHeading1 />
</span>
<span
onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
className={getClasses(editor.isActive('heading', { level: 2 }))}
>
<LuHeading2 />
</span>

<span
onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
className={getClasses(editor.isActive('heading', { level: 3 }))}
>
<LuHeading3 />
</span>

<Tooltip title="Code block">
<span
onClick={() => editor.chain().focus().toggleCodeBlock().run()}
className={getClasses(editor.isActive('codeBlock'))}
>
<LuCode2 />
</span>
</Tooltip>


<Tooltip title="Bullet list">
<span
onClick={() => editor.chain().focus().toggleBulletList().run()}
className={getClasses(editor.isActive('bulletList'))}
>
<LuList />
</span>
</Tooltip>


<Tooltip title="Ordered list">
<span
onClick={() => editor.chain().focus().toggleOrderedList().run()}
className={getClasses(editor.isActive('orderedList'))}
>
<LuListOrdered />
</span>
</Tooltip>

<Tooltip title="Bold">
<span
onClick={() => editor.chain().focus().toggleBold().run()}
className={getClasses(editor.isActive('bold'))}
>
<LuBold />
</span>
</Tooltip>

<Tooltip title="Italic">
<span
onClick={() => editor.chain().focus().toggleItalic().run()}
className={getClasses(editor.isActive('italic'))}
>
<LuItalic />
</span>
</Tooltip>

<Tooltip title="Linethrough">
<span
onClick={() => editor.chain().focus().toggleStrike().run()}
className={getClasses(editor.isActive('strike'))}
>
<LuStrikethrough />
</span>
</Tooltip>
<span
onClick={setImage}
className={getClasses(editor.isActive('strike'))}
>
<LuImage />
</span>

<Tooltip title="Hard break">
<span
onClick={() => editor.chain().focus().setHardBreak().run()}
className="bubble-action-btn"
>
<LuCornerUpLeft />
</span>
</Tooltip>
</div>
</BubbleMenu>
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { ChangeEvent, useEffect, useState } from 'react'
import { useEditor, EditorContent } from '@tiptap/react'
import { useEditor, EditorContent, BubbleMenu } from '@tiptap/react'

import StarterKit from '@tiptap/starter-kit'
import Link from '@tiptap/extension-link'
import Image from "@tiptap/extension-image";
import { TextareaProps, TexteditorProps } from '../type'
import { LuBold, LuItalic, LuStrikethrough, LuListOrdered, LuList } from "react-icons/lu";

import './style.css'
import BubbleEditorMenu from './BubbleEditorMenu'

import { TextareaProps, TexteditorProps } from '../type'

export default function TextareaControl({
title,
Expand All @@ -28,7 +31,7 @@ export default function TextareaControl({
// };

const editor = useEditor({
extensions: [StarterKit, Link.configure({ openOnClick: false })],
extensions: [StarterKit, Image, Link.configure({ openOnClick: false })],
content: val,
editable: !disabled,
onUpdate: ({ editor }) => {
Expand All @@ -51,24 +54,16 @@ export default function TextareaControl({
readOnly && classes.push('readonly')
error && classes.push('error')


return (
<div className={classes.join(' ')}>
{title ? <label>{title}</label> : null}
<div className="relative form-control-wrapper inline-flex w-full">
<div className="form-input">
{editor && <BubbleEditorMenu editor={editor} />
}
<EditorContent className="text-editor" spellCheck={false} editor={editor} />
</div>
{/* <textarea */}
{/* value={val} */}
{/* name={name} */}
{/* cols={cols} */}
{/* rows={rows} */}
{/* disabled={disabled} */}
{/* readOnly={readOnly} */}
{/* onChange={onInputChange} */}
{/* placeholder={placeholder} */}
{/* className="form-input" */}
{/* /> */}
</div>
{helper && !error ? (
<p className="mt-2 text-sm text-gray-500">{helper}</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
.text-editor .ProseMirror {
min-height: 100px;
}

.bubble-action-btn {
@apply cursor-pointer bg-gray-100 text-gray-500;
@apply border rounded w-6 h-6 flex justify-center items-center;
@apply dark:border-gray-700 dark:text-gray-500 dark:bg-gray-800;
@apply hover:bg-white dark:hover:bg-gray-700;
}

.bubble-action-btn.is-active {
@apply dark:bg-gray-900 dark:text-gray-400 dark:border-gray-500;
@apply bg-gray-200 text-gray-800 border-gray-400;
}

.ProseMirror-focused {
border: none;
outline: none;
Expand All @@ -10,6 +23,10 @@
@apply space-y-6;
}

.ProseMirror pre {
@apply p-4 rounded-md bg-black text-white text-xs;
}

.ProseMirror h1,
.ProseMirror h2,
.ProseMirror h3 {
Expand All @@ -19,6 +36,18 @@
.ProseMirror h1 {
font-size: 2rem;
}

.ProseMirror img {
@apply block mx-auto;
@apply my-6;
max-height: 700px;

}

img.ProseMirror-selectednode {
@apply outline outline-2 outline-offset-2 outline-indigo-400;
}

.ProseMirror h2 {
font-size: 1.5rem;
}
Expand Down

0 comments on commit cb7b4de

Please sign in to comment.