-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ac2d230
commit 13c02b9
Showing
27 changed files
with
2,449 additions
and
8,521 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const Divider = () => { | ||
return ( | ||
<div className="bg-black h-5 w-0.5 mx-5" /> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
"use client" | ||
import { useEditor, EditorContent } from '@tiptap/react' | ||
import StarterKit from '@tiptap/starter-kit' | ||
import { Toolbar } from './toolbar' | ||
import Underline from '@tiptap/extension-underline'; | ||
import { Link } from '@tiptap/extension-link'; | ||
import { BubbleMenu } from '@tiptap/extension-bubble-menu'; | ||
import { EditorBubbleMenu } from './bubbleMenu'; | ||
import React from 'react'; | ||
import './styles.css'; | ||
|
||
const Tiptap = () => { | ||
const editor = useEditor({ | ||
autofocus: true, | ||
editable: false, | ||
extensions: [ | ||
StarterKit, Underline, | ||
BubbleMenu, | ||
Link.configure({ | ||
openOnClick: true, | ||
autolink: true, | ||
}), | ||
], | ||
content: {"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"type":"text","text":"Hello World"}]},{"type":"heading","attrs":{"level":2},"content":[{"type":"text","marks":[{"type":"bold"},{"type":"italic"},{"type":"strike"},{"type":"underline"}],"text":"This is generate"}]},{"type":"bulletList","content":[{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"Task 1"}]}]},{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"Task 2"}]}]}]},{"type":"orderedList","attrs":{"start":1},"content":[{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"Task 3"}]}]},{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"Task 4"}]}]}]},{"type":"paragraph","content":[{"type":"text","marks":[{"type":"link","attrs":{"href":"https://generatenu.com","target":"_blank","rel":"noopener noreferrer nofollow","class":null}}],"text":"link"}]}]}, | ||
}) | ||
|
||
return ( | ||
<> | ||
<Toolbar editor={editor}/> | ||
{editor && <EditorBubbleMenu editor={editor}/>} | ||
<EditorContent className="h-15 pl-10 p-5 rounded-md bg-slate-200" editor={editor} /> | ||
</> | ||
) | ||
} | ||
|
||
export default Tiptap; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
.tiptap { | ||
> * + * { | ||
margin-top: 0.75em; | ||
} | ||
|
||
a { | ||
color: revert; | ||
text-decoration: revert; | ||
} | ||
|
||
ul, ol { | ||
list-style: revert; | ||
padding-left: revert; | ||
} | ||
|
||
h1, h2 { | ||
font-size: revert; | ||
font-weight: revert; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import { Editor } from '@tiptap/react' | ||
import {Bold, Italic, Strikethrough, | ||
Heading1, Heading2, ListOrdered, | ||
Undo, Redo, Unlink, | ||
ListIcon, UnderlineIcon} from 'lucide-react'; | ||
import { useState } from 'react'; | ||
import { Divider } from './divider'; | ||
import { HyperlinkButton } from './hyperlink'; | ||
import { Button } from "@/components/ui/button"; | ||
|
||
interface ToolbarProps { | ||
editor: Editor | null; | ||
} | ||
|
||
export const Toolbar: React.FC<ToolbarProps> = ({ editor }) => { | ||
if (!editor) { | ||
return null | ||
} | ||
|
||
const [json, setJSON] = useState("") | ||
|
||
return ( | ||
<div className="flex flex-row bg-slate-200 p-2 rounded-md items-center mb-2 justify-between flex-wrap"> | ||
<div className="ml-1 flex flex-row items-center flex-wrap space-x-1"> | ||
<Button onClick={() => editor.chain().focus().toggleBold().run()} | ||
disabled={!editor.isEditable} | ||
variant="link" | ||
size="link" | ||
className={editor.isActive('bold') && editor.isEditable ? 'bg-slate-300 rounded-md p-1.5' : 'p-1.5'}> | ||
<Bold /> | ||
</Button> | ||
<Button disabled={!editor.isEditable} | ||
variant="link" | ||
size="link" | ||
onClick={() => editor.chain().focus().toggleItalic().run()} | ||
className={editor.isActive('italic') && editor.isEditable ? 'bg-slate-300 rounded-md p-1.5' : 'p-1.5'}> | ||
<Italic /> | ||
</Button> | ||
<Button variant="link" | ||
size="link" disabled={!editor.isEditable} onClick={() => editor.chain().focus().toggleStrike().run()} | ||
className={editor.isActive('strike') && editor.isEditable ? 'bg-slate-300 rounded-md p-1.5' : 'p-1.5'}> | ||
<Strikethrough /> | ||
</Button> | ||
<Button variant="link" | ||
size="link" disabled={!editor.isEditable} onClick={() => editor.chain().focus().toggleUnderline().run()} | ||
className={editor.isActive('underline') && editor.isEditable ? 'bg-slate-300 rounded-md p-1.5' : 'p-1.5'}> | ||
<UnderlineIcon /> | ||
</Button> | ||
<Divider /> | ||
<Button variant="link" | ||
size="link" disabled={!editor.isEditable} onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()} | ||
className={editor.isActive('heading', { level: 1 }) && editor.isEditable ? 'bg-slate-300 rounded-md p-1.5' : 'p-1.5'}> | ||
<Heading1 /> | ||
</Button> | ||
<Button variant="link" | ||
size="link" disabled={!editor.isEditable} onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()} | ||
className={editor.isActive('heading', { level: 2 }) && editor.isEditable ? 'bg-slate-300 rounded-md p-1.5' : 'p-1.5'}> | ||
<Heading2 /> | ||
</Button> | ||
<Divider /> | ||
<Button variant="link" | ||
size="link" disabled={!editor.isEditable} onClick={() => editor.chain().focus().toggleBulletList().run()} | ||
className={editor.isActive('bulletList') && editor.isEditable ? 'bg-slate-300 rounded-md p-1.5' : 'p-1.5'}> | ||
<ListIcon /> | ||
</Button> | ||
<Button variant="link" | ||
size="link" disabled={!editor.isEditable} onClick={() => editor.chain().focus().toggleOrderedList().run()} | ||
className={editor.isActive('orderedList') && editor.isEditable ? 'bg-slate-300 rounded-md p-1.5' : 'p-1.5'}> | ||
<ListOrdered /> | ||
</Button> | ||
<HyperlinkButton disabled={!editor.isEditable} editor={editor}/> | ||
<Button | ||
variant="link" | ||
size="link" | ||
onClick={() => { | ||
editor.chain().focus().unsetLink().run(); | ||
}} | ||
disabled={!editor.isActive('link') || !editor.isEditable} | ||
className="p-1.5" | ||
> | ||
<Unlink /> | ||
</Button> | ||
<Divider /> | ||
<Button variant="link" | ||
size="link" disabled={!editor.isEditable} className="p-1.5" onClick={() => editor.chain().focus().undo().run()}> | ||
<Undo /> | ||
</Button> | ||
<Button variant="link" | ||
size="link" disabled={!editor.isEditable} className="p-1.5" onClick={() => editor.chain().focus().redo().run()}> | ||
<Redo /> | ||
</Button> | ||
</div> | ||
|
||
<Button onClick={() => { | ||
setJSON(JSON.stringify(editor.getJSON())); | ||
editor.setEditable(!editor.isEditable); | ||
}} | ||
className="px-4 py-1 bg-black rounded-md text-white text-sm">{editor.isEditable ? "Save" : "Edit"}</Button> | ||
</div> | ||
) | ||
} |
Oops, something went wrong.