1- import { useLayoutEffect , useRef } from 'react' ;
1+ import { type ComponentProps , useCallback , useLayoutEffect , useMemo , useRef } from 'react' ;
22
33import type { QAProps } from '@gravity-ui/uikit' ;
4- import { useUpdate } from 'react-use' ;
54
65import { LAYOUT } from 'src/common/layout' ;
6+ import { typedMemo } from 'src/react-utils/memo' ;
7+ import { EventEmitter } from 'src/utils' ;
78
89import type { ClassNameProps } from '../classname' ;
910import { i18n } from '../i18n/menubar' ;
1011import { useSticky } from '../react-utils/useSticky' ;
11- import { FlexToolbar , type ToolbarData , type ToolbarDisplay , type ToolbarItemData } from '../toolbar' ;
12+ import {
13+ FlexToolbar ,
14+ type FlexToolbarProps ,
15+ type ToolbarData ,
16+ type ToolbarDisplay ,
17+ type ToolbarItemData ,
18+ ToolbarProvider ,
19+ } from '../toolbar' ;
1220
1321import type { EditorInt } from './Editor' ;
1422import { stickyCn } from './sticky' ;
1523import type { MarkdownEditorMode } from './types' ;
1624
25+ const MemoizedFlexibleToolbar = typedMemo ( FlexToolbar ) ;
26+
27+ type ToolbarProviderValue = NonNullable < ComponentProps < typeof ToolbarProvider > [ 'value' ] > ;
28+
1729export type ToolbarViewProps < T > = ClassNameProps &
1830 QAProps & {
1931 editor : EditorInt ;
2032 editorMode : MarkdownEditorMode ;
2133 toolbarEditor : T ;
22- toolbarFocus : ( ) => void ;
2334 toolbarConfig : ToolbarData < T > ;
2435 settingsVisible ?: boolean ;
2536 hiddenActionsConfig ?: ToolbarItemData < T > [ ] ;
@@ -32,7 +43,6 @@ export function ToolbarView<T>({
3243 editor,
3344 editorMode,
3445 toolbarEditor,
35- toolbarFocus,
3646 toolbarConfig,
3747 toolbarDisplay,
3848 hiddenActionsConfig,
@@ -42,19 +52,40 @@ export function ToolbarView<T>({
4252 stickyToolbar,
4353 qa,
4454} : ToolbarViewProps < T > ) {
45- const rerender = useUpdate ( ) ;
46- useLayoutEffect ( ( ) => {
47- editor . on ( 'rerender-toolbar' , rerender ) ;
48- return ( ) => {
49- editor . off ( 'rerender-toolbar' , rerender ) ;
50- } ;
51- } , [ editor , rerender ] ) ;
52-
5355 const wrapperRef = useRef < HTMLDivElement > ( null ) ;
5456 const isStickyActive = useSticky ( wrapperRef ) && stickyToolbar ;
5557
5658 const mobile = editor . mobile ;
5759
60+ const clickHandle = useCallback < NonNullable < FlexToolbarProps < T > [ 'onClick' ] > > (
61+ ( id , attrs ) => editor . emit ( 'toolbar-action' , { id, attrs, editorMode} ) ,
62+ [ editor , editorMode ] ,
63+ ) ;
64+
65+ const toolbarProviderValue = useMemo (
66+ ( ) =>
67+ ( {
68+ editor : toolbarEditor ,
69+ eventBus : new EventEmitter < { update : null } > ( ) ,
70+ } ) satisfies ToolbarProviderValue ,
71+ [ toolbarEditor ] ,
72+ ) ;
73+
74+ const handleFocus = useCallback ( ( ) => {
75+ editor . focus ( ) ;
76+ } , [ editor ] ) ;
77+
78+ useLayoutEffect ( ( ) => {
79+ const onRerender = ( ) => {
80+ toolbarProviderValue . eventBus . emit ( 'update' , null ) ;
81+ } ;
82+
83+ editor . on ( 'rerender-toolbar' , onRerender ) ;
84+ return ( ) => {
85+ editor . off ( 'rerender-toolbar' , onRerender ) ;
86+ } ;
87+ } , [ editor , toolbarProviderValue ] ) ;
88+
5889 return (
5990 < div
6091 data-qa = { qa }
@@ -69,18 +100,20 @@ export function ToolbarView<T>({
69100 ) }
70101 data-layout = { LAYOUT . STICKY_TOOLBAR }
71102 >
72- < FlexToolbar
73- data = { toolbarConfig }
74- hiddenActions = { hiddenActionsConfig }
75- editor = { toolbarEditor }
76- focus = { toolbarFocus }
77- dotsTitle = { i18n ( 'more_action' ) }
78- onClick = { ( id , attrs ) => editor . emit ( 'toolbar-action' , { id, attrs, editorMode} ) }
79- display = { toolbarDisplay }
80- disableTooltip = { mobile }
81- disableHotkey = { mobile }
82- disablePreview = { mobile }
83- />
103+ < ToolbarProvider value = { toolbarProviderValue } >
104+ < MemoizedFlexibleToolbar
105+ data = { toolbarConfig }
106+ hiddenActions = { hiddenActionsConfig }
107+ editor = { toolbarEditor }
108+ focus = { handleFocus }
109+ dotsTitle = { i18n ( 'more_action' ) }
110+ onClick = { clickHandle }
111+ display = { toolbarDisplay }
112+ disableTooltip = { mobile }
113+ disableHotkey = { mobile }
114+ disablePreview = { mobile }
115+ />
116+ </ ToolbarProvider >
84117 { children }
85118 </ div >
86119 ) ;
0 commit comments