@@ -31,8 +31,8 @@ export class Menu {
3131 private readonly menuItems : MenuItem [ ] = [ ] ;
3232
3333 /**
34- * Coordinates of the mousedown event that caused this menu to open. Used to
35- * prevent the consequent mouseup event due to a simple click from
34+ * Coordinates of the pointerdown event that caused this menu to open. Used to
35+ * prevent the consequent pointerup event due to a simple click from
3636 * activating a menu item immediately.
3737 */
3838 openingCoords : Coordinate | null = null ;
@@ -43,17 +43,17 @@ export class Menu {
4343 */
4444 private highlightedItem : MenuItem | null = null ;
4545
46- /** Mouse over event data. */
47- private mouseOverHandler : browserEvents . Data | null = null ;
46+ /** Pointer over event data. */
47+ private pointerMoveHandler : browserEvents . Data | null = null ;
4848
4949 /** Click event data. */
5050 private clickHandler : browserEvents . Data | null = null ;
5151
52- /** Mouse enter event data. */
53- private mouseEnterHandler : browserEvents . Data | null = null ;
52+ /** Pointer enter event data. */
53+ private pointerEnterHandler : browserEvents . Data | null = null ;
5454
55- /** Mouse leave event data. */
56- private mouseLeaveHandler : browserEvents . Data | null = null ;
55+ /** Pointer leave event data. */
56+ private pointerLeaveHandler : browserEvents . Data | null = null ;
5757
5858 /** Key down event data. */
5959 private onKeyDownHandler : browserEvents . Data | null = null ;
@@ -99,11 +99,11 @@ export class Menu {
9999 }
100100
101101 // Add event handlers.
102- this . mouseOverHandler = browserEvents . conditionalBind (
102+ this . pointerMoveHandler = browserEvents . conditionalBind (
103103 element ,
104- 'pointerover ' ,
104+ 'pointermove ' ,
105105 this ,
106- this . handleMouseOver ,
106+ this . handlePointerMove ,
107107 true ,
108108 ) ;
109109 this . clickHandler = browserEvents . conditionalBind (
@@ -113,18 +113,18 @@ export class Menu {
113113 this . handleClick ,
114114 true ,
115115 ) ;
116- this . mouseEnterHandler = browserEvents . conditionalBind (
116+ this . pointerEnterHandler = browserEvents . conditionalBind (
117117 element ,
118118 'pointerenter' ,
119119 this ,
120- this . handleMouseEnter ,
120+ this . handlePointerEnter ,
121121 true ,
122122 ) ;
123- this . mouseLeaveHandler = browserEvents . conditionalBind (
123+ this . pointerLeaveHandler = browserEvents . conditionalBind (
124124 element ,
125125 'pointerleave' ,
126126 this ,
127- this . handleMouseLeave ,
127+ this . handlePointerLeave ,
128128 true ,
129129 ) ;
130130 this . onKeyDownHandler = browserEvents . conditionalBind (
@@ -183,21 +183,21 @@ export class Menu {
183183 /** Dispose of this menu. */
184184 dispose ( ) {
185185 // Remove event handlers.
186- if ( this . mouseOverHandler ) {
187- browserEvents . unbind ( this . mouseOverHandler ) ;
188- this . mouseOverHandler = null ;
186+ if ( this . pointerMoveHandler ) {
187+ browserEvents . unbind ( this . pointerMoveHandler ) ;
188+ this . pointerMoveHandler = null ;
189189 }
190190 if ( this . clickHandler ) {
191191 browserEvents . unbind ( this . clickHandler ) ;
192192 this . clickHandler = null ;
193193 }
194- if ( this . mouseEnterHandler ) {
195- browserEvents . unbind ( this . mouseEnterHandler ) ;
196- this . mouseEnterHandler = null ;
194+ if ( this . pointerEnterHandler ) {
195+ browserEvents . unbind ( this . pointerEnterHandler ) ;
196+ this . pointerEnterHandler = null ;
197197 }
198- if ( this . mouseLeaveHandler ) {
199- browserEvents . unbind ( this . mouseLeaveHandler ) ;
200- this . mouseLeaveHandler = null ;
198+ if ( this . pointerLeaveHandler ) {
199+ browserEvents . unbind ( this . pointerLeaveHandler ) ;
200+ this . pointerLeaveHandler = null ;
201201 }
202202 if ( this . onKeyDownHandler ) {
203203 browserEvents . unbind ( this . onKeyDownHandler ) ;
@@ -326,14 +326,26 @@ export class Menu {
326326 }
327327 }
328328
329- // Mouse events.
329+ // Pointer events.
330330
331331 /**
332- * Handles mouseover events. Highlight menuitems as the user hovers over them.
332+ * Handles pointermove events. Highlight menu items as the user hovers over
333+ * them.
333334 *
334- * @param e Mouse event to handle.
335+ * @param e Pointer event to handle.
335336 */
336- private handleMouseOver ( e : PointerEvent ) {
337+ private handlePointerMove ( e : PointerEvent ) {
338+ // Check whether the pointer actually did move. Move events are triggered if
339+ // the element underneath the pointer moves, even if the pointer itself has
340+ // remained stationary. In the case where the pointer is hovering over
341+ // the menu but the user is navigating through the list of items via the
342+ // keyboard and causing items off the end of the menu to scroll into view,
343+ // a pointermove event would be triggered due to the pointer now being over
344+ // a new child, but we don't want to highlight the item that's now under the
345+ // pointer.
346+ const delta = Math . max ( Math . abs ( e . movementX ) , Math . abs ( e . movementY ) ) ;
347+ if ( delta === 0 ) return ;
348+
337349 const menuItem = this . getMenuItem ( e . target as Element ) ;
338350
339351 if ( menuItem ) {
@@ -359,11 +371,11 @@ export class Menu {
359371 if ( oldCoords && typeof e . clientX === 'number' ) {
360372 const newCoords = new Coordinate ( e . clientX , e . clientY ) ;
361373 if ( Coordinate . distance ( oldCoords , newCoords ) < 1 ) {
362- // This menu was opened by a mousedown and we're handling the consequent
363- // click event. The coords haven't changed, meaning this was the same
364- // opening event. Don't do the usual behavior because the menu just
365- // popped up under the mouse and the user didn't mean to activate this
366- // item.
374+ // This menu was opened by a pointerdown and we're handling the
375+ // consequent click event. The coords haven't changed, meaning this was
376+ // the same opening event. Don't do the usual behavior because the menu
377+ // just popped up under the pointer and the user didn't mean to activate
378+ // this item.
367379 return ;
368380 }
369381 }
@@ -375,22 +387,21 @@ export class Menu {
375387 }
376388
377389 /**
378- * Handles mouse enter events. Focus the element.
390+ * Handles pointer enter events. Focus the element.
379391 *
380- * @param _e Mouse event to handle.
392+ * @param _e Pointer event to handle.
381393 */
382- private handleMouseEnter ( _e : PointerEvent ) {
394+ private handlePointerEnter ( _e : PointerEvent ) {
383395 this . focus ( ) ;
384396 }
385397
386398 /**
387- * Handles mouse leave events. Blur and clear highlight.
399+ * Handles pointer leave events by clearing the active highlight.
388400 *
389- * @param _e Mouse event to handle.
401+ * @param _e Pointer event to handle.
390402 */
391- private handleMouseLeave ( _e : PointerEvent ) {
403+ private handlePointerLeave ( _e : PointerEvent ) {
392404 if ( this . getElement ( ) ) {
393- this . blur ( ) ;
394405 this . setHighlighted ( null ) ;
395406 }
396407 }
0 commit comments