1
- /* eslint-disable react/no-duplicate-key */
2
1
import React , { useMemo } from 'react'
3
2
import type { Editor } from '@tiptap/core'
3
+ import type { ToolbarItemProps , ToolbarProps } from '@/types'
4
4
5
5
import { Separator } from '@/components'
6
6
import { useLocale } from '@/locales'
7
7
import { isFunction } from '@/utils/utils'
8
8
9
- export interface ToolbarProps {
9
+ export interface ToolbarComponentProps {
10
10
editor : Editor
11
11
disabled ?: boolean
12
+ toolbar ?: ToolbarProps
12
13
}
13
14
14
- interface ToolbarItemProps {
15
- button : {
16
- component : React . ComponentType < any >
17
- componentProps : Record < string , any >
18
- }
19
- divider : boolean
20
- spacer : boolean
21
- }
22
-
23
- function Toolbar ( { editor, disabled } : ToolbarProps ) {
15
+ function Toolbar ( { editor, disabled, toolbar } : ToolbarComponentProps ) {
24
16
const { t, lang } = useLocale ( )
25
17
26
- const items = useMemo ( ( ) => {
18
+ const toolbarItems = useMemo ( ( ) => {
27
19
const extensions = [ ...editor . extensionManager . extensions ]
28
20
const sortExtensions = extensions . sort ( ( arr , acc ) => {
29
21
const a = ( arr . options ) . sort ?? - 1
@@ -34,7 +26,12 @@ function Toolbar({ editor, disabled }: ToolbarProps) {
34
26
let menus : ToolbarItemProps [ ] = [ ]
35
27
36
28
for ( const extension of sortExtensions ) {
37
- const { button, divider = false , spacer = false , toolbar = true } = extension . options as any
29
+ const {
30
+ button,
31
+ divider = false ,
32
+ spacer = false ,
33
+ toolbar = true ,
34
+ } = extension . options
38
35
if ( ! button || ! isFunction ( button ) || ! toolbar ) {
39
36
continue
40
37
}
@@ -50,44 +47,62 @@ function Toolbar({ editor, disabled }: ToolbarProps) {
50
47
button : k ,
51
48
divider : i === _button . length - 1 ? divider : false ,
52
49
spacer : i === 0 ? spacer : false ,
50
+ type : extension . type ,
51
+ name : extension . name ,
53
52
} ) )
54
53
menus = [ ...menus , ...menu ]
55
54
continue
56
55
}
57
56
58
- menus . push ( { button : _button , divider, spacer } )
57
+ menus . push ( {
58
+ button : _button ,
59
+ divider,
60
+ spacer,
61
+ type : extension . type ,
62
+ name : extension . name ,
63
+ } )
59
64
}
60
65
return menus
61
66
} , [ editor , t , lang ] )
62
67
63
- return (
64
- < div
65
- className = "richtext-px-1 richtext-py-2 !richtext-border-b"
66
- style = { {
67
- pointerEvents : disabled ? 'none' : 'auto' ,
68
- opacity : disabled ? 0.5 : 1 ,
69
- } }
70
- >
71
- < div className = "richtext-relative richtext-flex richtext-flex-wrap richtext-h-auto richtext-gap-y-1 richtext-gap-x-1" >
72
- { items . map ( ( item : ToolbarItemProps , key ) => {
73
- const ButtonComponent = item . button . component
74
-
75
- return (
76
- < div className = "richtext-flex richtext-items-center" key = { `toolbar-item-${ key } ` } >
77
- { item ?. spacer && < Separator orientation = "vertical" className = "!richtext-h-[16px] !richtext-mx-[10px]" /> }
78
-
79
- < ButtonComponent
80
- { ...item . button . componentProps }
81
- disabled = { disabled || item ?. button ?. componentProps ?. disabled }
82
- />
83
-
84
- { item ?. divider && < Separator orientation = "vertical" className = "!richtext-h-auto !richtext-mx-2" /> }
85
- </ div >
86
- )
87
- } ) }
68
+ const containerDom = ( innerContent : React . ReactNode ) => {
69
+ return (
70
+ < div
71
+ className = "richtext-px-1 richtext-py-2 !richtext-border-b"
72
+ style = { {
73
+ pointerEvents : disabled ? 'none' : 'auto' ,
74
+ opacity : disabled ? 0.5 : 1 ,
75
+ } }
76
+ >
77
+ < div className = "richtext-relative richtext-flex richtext-flex-wrap richtext-h-auto richtext-gap-y-1 richtext-gap-x-1" >
78
+ { innerContent }
79
+ </ div >
88
80
</ div >
89
- </ div >
90
- )
81
+ )
82
+ }
83
+
84
+ const dom = toolbarItems . map ( ( item : ToolbarItemProps , key ) => {
85
+ const ButtonComponent = item . button . component
86
+
87
+ return (
88
+ < div className = "richtext-flex richtext-items-center" key = { `toolbar-item-${ key } ` } >
89
+ { item ?. spacer && < Separator orientation = "vertical" className = "!richtext-h-[16px] !richtext-mx-[10px]" /> }
90
+
91
+ < ButtonComponent
92
+ { ...item . button . componentProps }
93
+ disabled = { disabled || item ?. button ?. componentProps ?. disabled }
94
+ />
95
+
96
+ { item ?. divider && < Separator orientation = "vertical" className = "!richtext-h-auto !richtext-mx-2" /> }
97
+ </ div >
98
+ )
99
+ } )
100
+
101
+ if ( toolbar && toolbar ?. render ) {
102
+ return toolbar . render ( { editor, disabled : disabled || false } , toolbarItems , dom , containerDom )
103
+ }
104
+
105
+ return containerDom ( dom )
91
106
}
92
107
93
108
export { Toolbar }
0 commit comments