@@ -6,9 +6,11 @@ import {
66 BoldIcon ,
77 ItalicIcon ,
88 CodeIcon ,
9+ QuoteIcon ,
10+ MinusSquareIcon ,
11+ Type as TextIcon ,
12+ Heading ,
913} from "lucide-react" ;
10-
11- import { NodeSelector } from "./node-selector" ;
1214import { LinkSelector } from "./link-selector" ;
1315import { cn } from "@/utils/utils" ;
1416
@@ -23,34 +25,56 @@ type EditorBubbleMenuProps = Omit<Required<Pick<BubbleMenuProps, "editor">> & Bu
2325
2426export const EditorBubbleMenu : FC < EditorBubbleMenuProps > = ( props ) => {
2527 const items : BubbleMenuItem [ ] = [
28+ {
29+ name : "heading" ,
30+ isActive : ( ) => props . editor ?. isActive ( "heading" , { level : 2 } ) ?? false ,
31+ command : ( ) => props . editor ?. chain ( ) . focus ( ) . toggleHeading ( { level : 2 } ) . run ( ) ,
32+ icon : Heading ,
33+ } ,
34+ {
35+ name : "text" ,
36+ isActive : ( ) => props . editor ?. isActive ( "paragraph" ) ?? false ,
37+ command : ( ) => props . editor ?. chain ( ) . focus ( ) . setParagraph ( ) . run ( ) ,
38+ icon : TextIcon ,
39+ } ,
2640 {
2741 name : "bold" ,
28- isActive : ( ) => props . editor . isActive ( "bold" ) ,
29- command : ( ) => props . editor . chain ( ) . focus ( ) . toggleBold ( ) . run ( ) ,
42+ isActive : ( ) => props . editor ? .isActive ( "bold" ) ?? false ,
43+ command : ( ) => props . editor ? .chain ( ) . focus ( ) . toggleBold ( ) . run ( ) ,
3044 icon : BoldIcon ,
3145 } ,
3246 {
3347 name : "italic" ,
34- isActive : ( ) => props . editor . isActive ( "italic" ) ,
35- command : ( ) => props . editor . chain ( ) . focus ( ) . toggleItalic ( ) . run ( ) ,
48+ isActive : ( ) => props . editor ? .isActive ( "italic" ) ?? false ,
49+ command : ( ) => props . editor ? .chain ( ) . focus ( ) . toggleItalic ( ) . run ( ) ,
3650 icon : ItalicIcon ,
3751 } ,
3852 {
3953 name : "code" ,
40- isActive : ( ) => props . editor . isActive ( "code" ) ,
41- command : ( ) => props . editor . chain ( ) . focus ( ) . toggleCode ( ) . run ( ) ,
54+ isActive : ( ) => props . editor ? .isActive ( "code" ) ?? false ,
55+ command : ( ) => props . editor ? .chain ( ) . focus ( ) . toggleCode ( ) . run ( ) ,
4256 icon : CodeIcon ,
4357 } ,
58+ {
59+ name : "quote" ,
60+ isActive : ( ) => props . editor ?. isActive ( "blockquote" ) ?? false ,
61+ command : ( ) => props . editor ?. chain ( ) . focus ( ) . toggleBlockquote ( ) . run ( ) ,
62+ icon : QuoteIcon ,
63+ } ,
64+ {
65+ name : "horizontalRule" ,
66+ isActive : ( ) => false ,
67+ command : ( ) => props . editor ?. chain ( ) . focus ( ) . setHorizontalRule ( ) . run ( ) ,
68+ icon : MinusSquareIcon ,
69+ } ,
4470 ] ;
4571
4672 const bubbleMenuProps : EditorBubbleMenuProps = {
4773 ...props ,
4874 shouldShow : ( { editor } ) => {
49- // don't show if image is selected or a heading
50- if ( editor . isActive ( "image" ) || editor . isActive ( "heading" ) ) {
75+ if ( editor . isActive ( "image" ) ) {
5176 return false ;
5277 }
53-
5478 try {
5579 if ( editor . view . state . selection . $from . before ( ) === 0 ) {
5680 return false ;
@@ -65,36 +89,18 @@ export const EditorBubbleMenu: FC<EditorBubbleMenuProps> = (props) => {
6589 tippyOptions : {
6690 moveTransition : "transform 0.15s ease-out" ,
6791 onHidden : ( ) => {
68- setIsNodeSelectorOpen ( false ) ;
6992 setIsLinkSelectorOpen ( false ) ;
7093 } ,
7194 } ,
7295 } ;
7396
74- const [ isNodeSelectorOpen , setIsNodeSelectorOpen ] = useState ( false ) ;
7597 const [ isLinkSelectorOpen , setIsLinkSelectorOpen ] = useState ( false ) ;
7698
7799 return (
78100 < BubbleMenu
79101 { ...bubbleMenuProps }
80102 className = "flex w-fit divide-x divide-stone-200 rounded border border-stone-200 bg-white shadow-xl"
81103 >
82- < NodeSelector
83- editor = { props . editor }
84- isOpen = { isNodeSelectorOpen }
85- setIsOpen = { ( ) => {
86- setIsNodeSelectorOpen ( ! isNodeSelectorOpen ) ;
87- setIsLinkSelectorOpen ( false ) ;
88- } }
89- />
90- < LinkSelector
91- editor = { props . editor }
92- isOpen = { isLinkSelectorOpen }
93- setIsOpen = { ( ) => {
94- setIsLinkSelectorOpen ( ! isLinkSelectorOpen ) ;
95- setIsNodeSelectorOpen ( false ) ;
96- } }
97- />
98104 < div className = "flex" >
99105 { items . map ( ( item , index ) => (
100106 < button
@@ -111,6 +117,13 @@ export const EditorBubbleMenu: FC<EditorBubbleMenuProps> = (props) => {
111117 </ button >
112118 ) ) }
113119 </ div >
120+ < LinkSelector
121+ editor = { props . editor ! }
122+ isOpen = { isLinkSelectorOpen }
123+ setIsOpen = { ( ) => {
124+ setIsLinkSelectorOpen ( ! isLinkSelectorOpen ) ;
125+ } }
126+ />
114127 </ BubbleMenu >
115128 ) ;
116- } ;
129+ } ;
0 commit comments