@@ -6,16 +6,8 @@ import {
66 useLayoutEffect ,
77 useState
88} from 'react'
9- import {
10- GraphComponent ,
11- GraphViewerInputMode ,
12- IModelItem ,
13- Point ,
14- PopulateItemContextMenuEventArgs ,
15- TouchEventArgs
16- } from 'yfiles'
9+ import { GraphViewerInputMode , IModelItem , PopulateItemContextMenuEventArgs } from '@yfiles/yfiles'
1710import { useGraphComponent } from '../graph-component/GraphComponentProvider.tsx'
18- import { BrowserDetection } from '../utils/BrowserDetection.ts'
1911import './ContextMenu.css'
2012import { DefaultRenderMenu } from './DefaultRenderMenu.tsx'
2113
@@ -95,19 +87,6 @@ export function ContextMenu<TDataItem>({
9587
9688 const graphComponent = useGraphComponent ( ) !
9789
98- const openContextMenu = useCallback (
99- ( worldLocation : Point ) => {
100- const showMenu = (
101- graphComponent . inputMode as GraphViewerInputMode
102- ) . contextMenuInputMode . shouldOpenMenu ( worldLocation )
103- if ( showMenu ) {
104- setMenuVisible ( true )
105- setMenuLocation ( graphComponent . toViewCoordinates ( worldLocation ) )
106- }
107- } ,
108- [ graphComponent ]
109- )
110-
11190 const populateContextMenu = useCallback (
11291 ( args : PopulateItemContextMenuEventArgs < IModelItem > ) => {
11392 const modelItem = args . item
@@ -123,77 +102,33 @@ export function ContextMenu<TDataItem>({
123102 * Registers the context menu listeners.
124103 */
125104 useLayoutEffect ( ( ) => {
126- const componentDiv = graphComponent . div
127- const contextMenuListener = ( evt : MouseEvent ) => {
128- evt . preventDefault ( )
129- openContextMenu ( graphComponent . toWorldFromPage ( { x : evt . pageX , y : evt . pageY } ) )
130- }
131-
132- // Listen for the contextmenu event
133- // Note: On Linux based systems (e.g. Ubuntu), the contextmenu event is fired on mouse down
134- // which triggers the ContextMenuInputMode before the ClickInputMode. Therefore, handling the
135- // event, will prevent the ItemRightClicked event from firing.
136- // For more information, see https://docs.yworks.com/yfileshtml/#/kb/article/780/
137- componentDiv . addEventListener ( 'contextmenu' , contextMenuListener , false )
138-
139- let touchDownListener : ( _ : GraphComponent , evt : TouchEventArgs ) => void | null
140- let touchUpListener : ( _ : GraphComponent , evt : TouchEventArgs ) => void | null
141- if ( BrowserDetection . safariVersion > 0 || BrowserDetection . iOSVersion > 0 ) {
142- // Additionally add a long press listener especially for iOS, since it does not fire the contextmenu event.
143- let contextMenuTimer : ReturnType < typeof setTimeout > | undefined
144- touchDownListener = ( _ : GraphComponent , evt : TouchEventArgs ) => {
145- contextMenuTimer = setTimeout ( ( ) => {
146- openContextMenu ( evt . location )
147- } , 500 )
148- }
149- graphComponent . addTouchDownListener ( touchDownListener )
150- touchUpListener = ( ) => {
151- clearTimeout ( contextMenuTimer ! )
152- }
153- graphComponent . addTouchUpListener ( touchUpListener )
154- }
155-
156- // Listen to the context menu key to make it work in Chrome
157- const contextMenuKeyListener = ( evt : KeyboardEvent ) => {
158- if ( evt . key === 'ContextMenu' ) {
159- evt . preventDefault ( )
160- openContextMenu ( graphComponent . toWorldFromPage ( getCenterInPage ( componentDiv ) ) )
161- }
162- }
163- componentDiv . addEventListener ( 'keyup' , contextMenuKeyListener )
164-
165105 // register the close listener
166106 const closeMenuListener = ( ) => {
167107 setMenuVisible ( false )
168108 }
169109 const inputMode = graphComponent . inputMode as GraphViewerInputMode
170- inputMode . contextMenuInputMode . addCloseMenuListener ( closeMenuListener )
110+ inputMode . contextMenuInputMode . addEventListener ( 'menu-closed' , closeMenuListener )
171111
172112 // register populate items listener
173- const populateContextMenuListener = (
174- _ : GraphViewerInputMode ,
175- args : PopulateItemContextMenuEventArgs < IModelItem >
176- ) => {
113+ const populateContextMenuListener = ( event : PopulateItemContextMenuEventArgs < IModelItem > ) => {
177114 // select the item
178- if ( args . item ) {
115+ if ( event . item ) {
179116 graphComponent . selection . clear ( )
180- graphComponent . selection . setSelected ( args . item , true )
117+ graphComponent . selection . add ( event . item )
181118 }
119+ setMenuVisible ( true )
120+ setMenuLocation ( graphComponent . worldToViewCoordinates ( event . queryLocation ) )
182121 // populate the menu
183- populateContextMenu ( args )
122+ populateContextMenu ( event )
184123 }
185- inputMode . addPopulateItemContextMenuListener ( populateContextMenuListener )
124+ inputMode . addEventListener ( 'populate-item-context-menu' , populateContextMenuListener )
186125
187126 return ( ) => {
188127 // cleanup
189- componentDiv . removeEventListener ( 'contextmenu' , contextMenuListener )
190- componentDiv . removeEventListener ( 'keyup' , contextMenuKeyListener )
191- inputMode . contextMenuInputMode . removeCloseMenuListener ( closeMenuListener )
192- inputMode . removePopulateItemContextMenuListener ( populateContextMenuListener )
193- touchDownListener && graphComponent . removeTouchDownListener ( touchDownListener )
194- touchUpListener && graphComponent . removeTouchUpListener ( touchUpListener )
128+ inputMode . contextMenuInputMode . removeEventListener ( 'menu-closed' , closeMenuListener )
129+ inputMode . removeEventListener ( 'populate-item-context-menu' , populateContextMenuListener )
195130 }
196- } , [ graphComponent , openContextMenu , populateContextMenu ] )
131+ } , [ graphComponent , populateContextMenu ] )
197132
198133 return (
199134 < >
@@ -249,17 +184,3 @@ function ContextMenuCore<TDataItem>({
249184 )
250185 )
251186}
252-
253- /**
254- * Helper function to determine the page's center location.
255- */
256- function getCenterInPage ( element : HTMLElement ) : { x : number ; y : number } {
257- let left = element . clientWidth / 2.0
258- let top = element . clientHeight / 2.0
259- while ( element . offsetParent ) {
260- left += element . offsetLeft
261- top += element . offsetTop
262- element = element . offsetParent as HTMLElement
263- }
264- return { x : left , y : top }
265- }
0 commit comments