1+ import classNames from 'classnames' ;
12import type { ReactElement , ReactNode , Ref } from 'react' ;
23import React , {
34 useState ,
@@ -24,9 +25,13 @@ import { LinkModal } from './LinkModal';
2425export interface RichTextToolbarProps {
2526 editor : Editor ;
2627 onLinkAdd : ( url : string , label ?: string ) => void ;
28+ leadingActions ?: ReactNode ;
2729 inlineActions ?: ReactNode ;
2830 rightActions ?: ReactNode ;
2931 allowBlockFormatting ?: boolean ;
32+ position ?: 'top' | 'bottom' ;
33+ className ?: string ;
34+ hideInlineLink ?: boolean ;
3035}
3136
3237export interface RichTextToolbarRef {
@@ -47,8 +52,9 @@ const ToolbarButton = ({
4752 isActive,
4853 onClick,
4954 disabled = false ,
50- } : ToolbarButtonProps ) : ReactElement | null => {
51- if ( disabled ) {
55+ alwaysVisible = false ,
56+ } : ToolbarButtonProps & { alwaysVisible ?: boolean } ) : ReactElement | null => {
57+ if ( disabled && ! alwaysVisible ) {
5258 return null ;
5359 }
5460
@@ -64,6 +70,7 @@ const ToolbarButton = ({
6470 } ) }
6571 pressed = { isActive }
6672 onClick = { onClick }
73+ disabled = { disabled }
6774 type = "button"
6875 className = "leading-none"
6976 />
@@ -75,9 +82,13 @@ function RichTextToolbarComponent(
7582 {
7683 editor,
7784 onLinkAdd,
85+ leadingActions,
7886 inlineActions,
7987 rightActions,
8088 allowBlockFormatting = true ,
89+ position = 'top' ,
90+ className,
91+ hideInlineLink = false ,
8192 } : RichTextToolbarProps ,
8293 ref : Ref < RichTextToolbarRef > ,
8394) : ReactElement {
@@ -147,8 +158,29 @@ function RichTextToolbarComponent(
147158
148159 return (
149160 < >
150- < div className = "flex flex-row flex-wrap items-center gap-1 border-b border-border-subtlest-tertiary px-2 py-1" >
161+ < div
162+ className = { classNames (
163+ 'flex flex-row flex-wrap items-center gap-1 px-2 py-1' ,
164+ position === 'top' && 'border-b border-border-subtlest-tertiary' ,
165+ className ,
166+ ) }
167+ >
151168 < div className = "flex flex-1 flex-wrap items-center gap-0" >
169+ { leadingActions && (
170+ < div className = "mr-2 flex items-center gap-1" > { leadingActions } </ div >
171+ ) }
172+ { inlineActions && (
173+ < div className = "flex items-center gap-1" > { inlineActions } </ div >
174+ ) }
175+ { ! hideInlineLink && (
176+ < ToolbarButton
177+ tooltip = { editorState . isLink ? 'Edit link (⌘K)' : 'Add link (⌘K)' }
178+ icon = { < LinkIcon /> }
179+ isActive = { editorState . isLink }
180+ onClick = { openLinkModal }
181+ />
182+ ) }
183+ < div className = "mx-1 h-4 w-px bg-border-subtlest-tertiary" />
152184 < ToolbarButton
153185 tooltip = "Bold (⌘B)"
154186 icon = { < BoldIcon /> }
@@ -161,7 +193,7 @@ function RichTextToolbarComponent(
161193 isActive = { editorState . isItalic }
162194 onClick = { ( ) => editor . chain ( ) . focus ( ) . toggleItalic ( ) . run ( ) }
163195 />
164- { allowBlockFormatting ? (
196+ { allowBlockFormatting && (
165197 < >
166198 < div className = "mx-1 h-4 w-px bg-border-subtlest-tertiary" />
167199 < ToolbarButton
@@ -177,36 +209,23 @@ function RichTextToolbarComponent(
177209 onClick = { ( ) => editor . chain ( ) . focus ( ) . toggleOrderedList ( ) . run ( ) }
178210 />
179211 </ >
180- ) : null }
181- < div className = "mx-1 h-4 w-px bg-border-subtlest-tertiary" />
182- < ToolbarButton
183- tooltip = { editorState . isLink ? 'Edit link (⌘K)' : 'Add link (⌘K)' }
184- icon = { < LinkIcon /> }
185- isActive = { editorState . isLink }
186- onClick = { openLinkModal }
187- />
188- { inlineActions && (
189- < >
190- < div className = "mx-1 h-4 w-px bg-border-subtlest-tertiary" />
191- < div className = "flex items-center gap-1" > { inlineActions } </ div >
192- </ >
193- ) }
194- { ( editorState . canUndo || editorState . canRedo ) && (
195- < div className = "mx-1 h-4 w-px bg-border-subtlest-tertiary" />
196212 ) }
213+ < div className = "mx-1 h-4 w-px bg-border-subtlest-tertiary" />
197214 < ToolbarButton
198215 tooltip = "Undo (⌘Z)"
199216 icon = { < UndoIcon /> }
200217 isActive = { false }
201218 onClick = { ( ) => editor . chain ( ) . focus ( ) . undo ( ) . run ( ) }
202219 disabled = { ! editorState . canUndo }
220+ alwaysVisible
203221 />
204222 < ToolbarButton
205223 tooltip = "Redo (⌘⇧Z)"
206224 icon = { < RedoIcon /> }
207225 isActive = { false }
208226 onClick = { ( ) => editor . chain ( ) . focus ( ) . redo ( ) . run ( ) }
209227 disabled = { ! editorState . canRedo }
228+ alwaysVisible
210229 />
211230 </ div >
212231 { rightActions && (
0 commit comments