11import { Editor } from '@tiptap/react' ;
2- import { useEffect , useRef , useState } from 'react' ;
32
43interface Props {
54 editor : Editor | null ;
@@ -8,31 +7,10 @@ interface Props {
87}
98
109export default function Toolbar ( { editor, isHtmlMode, onToggleHtml } : Props ) {
11- const [ linkUrl , setLinkUrl ] = useState ( '' ) ;
12- const [ showLink , setShowLink ] = useState ( false ) ;
13- const linkAnchorRef = useRef < HTMLDivElement > ( null ) ;
14- const linkInputRef = useRef < HTMLInputElement > ( null ) ;
15-
16- // Close link popover on outside click
17- useEffect ( ( ) => {
18- if ( ! showLink ) return ;
19- const handle = ( e : MouseEvent ) => {
20- if ( ! linkAnchorRef . current ?. contains ( e . target as Node ) ) setShowLink ( false ) ;
21- } ;
22- document . addEventListener ( 'mousedown' , handle ) ;
23- return ( ) => document . removeEventListener ( 'mousedown' , handle ) ;
24- } , [ showLink ] ) ;
25-
26- useEffect ( ( ) => {
27- if ( showLink ) linkInputRef . current ?. focus ( ) ;
28- } , [ showLink ] ) ;
29-
3010 if ( ! editor ) return < div className = "rte-toolbar" /> ;
3111
3212 const dis = isHtmlMode ;
3313
34- // ── Helpers ──────────────────────────────────────────────────────────────
35-
3614 const headingLevel = ( ) : string => {
3715 for ( let i = 1 ; i <= 6 ; i ++ ) {
3816 if ( editor . isActive ( 'heading' , { level : i } ) ) return String ( i ) ;
@@ -48,31 +26,6 @@ export default function Toolbar({ editor, isHtmlMode, onToggleHtml }: Props) {
4826 }
4927 } ;
5028
51- const openLink = ( ) => {
52- setLinkUrl ( editor . getAttributes ( 'link' ) . href ?? '' ) ;
53- setShowLink ( true ) ;
54- } ;
55-
56- const applyLink = ( ) => {
57- const raw = linkUrl . trim ( ) ;
58- if ( ! raw ) {
59- editor . chain ( ) . focus ( ) . extendMarkRange ( 'link' ) . unsetLink ( ) . run ( ) ;
60- } else {
61- const href = / ^ h t t p s ? : \/ \/ / i. test ( raw ) ? raw : `https://${ raw } ` ;
62- editor . chain ( ) . focus ( ) . extendMarkRange ( 'link' ) . setLink ( { href } ) . run ( ) ;
63- }
64- setShowLink ( false ) ;
65- setLinkUrl ( '' ) ;
66- } ;
67-
68- const removeLink = ( ) => {
69- editor . chain ( ) . focus ( ) . extendMarkRange ( 'link' ) . unsetLink ( ) . run ( ) ;
70- setShowLink ( false ) ;
71- setLinkUrl ( '' ) ;
72- } ;
73-
74- // ── Render ────────────────────────────────────────────────────────────────
75-
7629 return (
7730 < div className = "rte-toolbar" >
7831
@@ -177,51 +130,6 @@ export default function Toolbar({ editor, isHtmlMode, onToggleHtml }: Props) {
177130
178131 < span className = "rte-divider" />
179132
180- { /* Link */ }
181- < div ref = { linkAnchorRef } className = "rte-link-anchor" >
182- < Btn
183- active = { editor . isActive ( 'link' ) }
184- disabled = { dis }
185- title = "Link"
186- onPress = { openLink }
187- > < LinkIcon /> </ Btn >
188-
189- { showLink && (
190- < div className = "rte-link-popover" >
191- < input
192- ref = { linkInputRef }
193- type = "url"
194- className = "rte-link-input"
195- placeholder = "https://example.com"
196- value = { linkUrl }
197- onChange = { e => setLinkUrl ( e . target . value ) }
198- onKeyDown = { e => {
199- if ( e . key === 'Enter' ) { e . preventDefault ( ) ; applyLink ( ) ; }
200- if ( e . key === 'Escape' ) setShowLink ( false ) ;
201- } }
202- />
203- < button
204- type = "button"
205- className = "rte-btn rte-btn-text"
206- onMouseDown = { e => { e . preventDefault ( ) ; applyLink ( ) ; } }
207- >
208- Apply
209- </ button >
210- { editor . isActive ( 'link' ) && (
211- < button
212- type = "button"
213- className = "rte-btn rte-btn-danger"
214- onMouseDown = { e => { e . preventDefault ( ) ; removeLink ( ) ; } }
215- >
216- Remove
217- </ button >
218- ) }
219- </ div >
220- ) }
221- </ div >
222-
223- < span className = "rte-divider" />
224-
225133 { /* Table */ }
226134 < Btn
227135 active = { false }
@@ -320,15 +228,6 @@ function HRIcon() {
320228 ) ;
321229}
322230
323- function LinkIcon ( ) {
324- return (
325- < svg width = "15" height = "15" viewBox = "0 0 15 15" fill = "none" stroke = "currentColor" strokeWidth = "1.5" strokeLinecap = "round" strokeLinejoin = "round" >
326- < path d = "M6 9.5a3.5 3.5 0 004.9-.1l1.5-1.5a3.5 3.5 0 00-4.95-4.95L6.4 4.1" />
327- < path d = "M9 5.5a3.5 3.5 0 00-4.9.1L2.6 7.1a3.5 3.5 0 004.95 4.95L8.6 10.9" />
328- </ svg >
329- ) ;
330- }
331-
332231function TableIcon ( ) {
333232 return (
334233 < svg width = "15" height = "15" viewBox = "0 0 15 15" fill = "none" stroke = "currentColor" strokeWidth = "1.25" >
0 commit comments