11import { Controller } from "@hotwired/stimulus" ;
2- import { computePosition , flip , shift , offset } from "@floating-ui/dom" ;
2+ import { computePosition , flip , shift , offset , autoUpdate } from "@floating-ui/dom" ;
33
44export default class extends Controller {
55 static targets = [ "trigger" , "content" , "menuItem" ] ;
@@ -12,11 +12,20 @@ export default class extends Controller {
1212 type : Object ,
1313 default : { } ,
1414 } ,
15- }
15+ } ;
1616
1717 connect ( ) {
1818 this . boundHandleKeydown = this . #handleKeydown. bind ( this ) ; // Bind the function so we can remove it later
1919 this . selectedIndex = - 1 ;
20+ this . cleanup = autoUpdate (
21+ this . triggerTarget ,
22+ this . contentTarget ,
23+ this . #computeTooltip. bind ( this ) ,
24+ ) ;
25+ }
26+
27+ disconnect ( ) {
28+ this . cleanup ( ) ;
2029 }
2130
2231 #computeTooltip( ) {
@@ -40,14 +49,16 @@ export default class extends Controller {
4049 }
4150
4251 toggle ( ) {
43- this . contentTarget . classList . contains ( "hidden" ) ? this . #open( ) : this . close ( ) ;
52+ this . contentTarget . classList . contains ( "hidden" )
53+ ? this . #open( )
54+ : this . close ( ) ;
4455 }
4556
4657 #open( ) {
4758 this . openValue = true ;
4859 this . #deselectAll( ) ;
4960 this . #addEventListeners( ) ;
50- this . #computeTooltip( )
61+ this . #computeTooltip( ) ;
5162 this . contentTarget . classList . remove ( "hidden" ) ;
5263 }
5364
@@ -59,15 +70,17 @@ export default class extends Controller {
5970
6071 #handleKeydown( e ) {
6172 // return if no menu items (one line fix for)
62- if ( this . menuItemTargets . length === 0 ) { return ; }
73+ if ( this . menuItemTargets . length === 0 ) {
74+ return ;
75+ }
6376
64- if ( e . key === ' ArrowDown' ) {
77+ if ( e . key === " ArrowDown" ) {
6578 e . preventDefault ( ) ;
6679 this . #updateSelectedItem( 1 ) ;
67- } else if ( e . key === ' ArrowUp' ) {
80+ } else if ( e . key === " ArrowUp" ) {
6881 e . preventDefault ( ) ;
6982 this . #updateSelectedItem( - 1 ) ;
70- } else if ( e . key === ' Enter' && this . selectedIndex !== - 1 ) {
83+ } else if ( e . key === " Enter" && this . selectedIndex !== - 1 ) {
7184 e . preventDefault ( ) ;
7285 this . menuItemTargets [ this . selectedIndex ] . click ( ) ;
7386 }
@@ -76,7 +89,7 @@ export default class extends Controller {
7689 #updateSelectedItem( direction ) {
7790 // Check if any of the menuItemTargets have aria-selected="true" and set the selectedIndex to that index
7891 this . menuItemTargets . forEach ( ( item , index ) => {
79- if ( item . getAttribute ( ' aria-selected' ) === ' true' ) {
92+ if ( item . getAttribute ( " aria-selected" ) === " true" ) {
8093 this . selectedIndex = index ;
8194 }
8295 } ) ;
@@ -99,22 +112,24 @@ export default class extends Controller {
99112 #toggleAriaSelected( element , isSelected ) {
100113 // Add or remove attribute
101114 if ( isSelected ) {
102- element . setAttribute ( ' aria-selected' , ' true' ) ;
115+ element . setAttribute ( " aria-selected" , " true" ) ;
103116 } else {
104- element . removeAttribute ( ' aria-selected' ) ;
117+ element . removeAttribute ( " aria-selected" ) ;
105118 }
106119 }
107120
108121 #deselectAll( ) {
109- this . menuItemTargets . forEach ( item => this . #toggleAriaSelected( item , false ) ) ;
122+ this . menuItemTargets . forEach ( ( item ) =>
123+ this . #toggleAriaSelected( item , false ) ,
124+ ) ;
110125 this . selectedIndex = - 1 ;
111126 }
112127
113128 #addEventListeners( ) {
114- document . addEventListener ( ' keydown' , this . boundHandleKeydown ) ;
129+ document . addEventListener ( " keydown" , this . boundHandleKeydown ) ;
115130 }
116131
117132 #removeEventListeners( ) {
118- document . removeEventListener ( ' keydown' , this . boundHandleKeydown ) ;
133+ document . removeEventListener ( " keydown" , this . boundHandleKeydown ) ;
119134 }
120135}
0 commit comments