@@ -89,7 +89,7 @@ export class Combobox {
8989 // Use setTimeout to ensure DOM is fully rendered before calculating position
9090 setTimeout ( ( ) => {
9191 this . updateListboxPosition ( ) ;
92- } , 0 ) ;
92+ } , 10 ) ;
9393 }
9494 }
9595
@@ -175,7 +175,7 @@ export class Combobox {
175175 } ) }
176176 role = "option"
177177 aria-selected = { index === this . highlightedIndex }
178- onClick = { ( e ) => this . handleOptionClick ( option , e ) }
178+ onMouseDown = { ( e ) => this . handleOptionClick ( option , e ) }
179179 onMouseEnter = { ( ) => {
180180 this . highlightedIndex = index ;
181181 } }
@@ -224,6 +224,13 @@ export class Combobox {
224224 ) ;
225225 this . filteredOptions = filtered ;
226226 this . highlightedIndex = - 1 ;
227+
228+ // Update listbox position when filtered options change (dropdown size changes)
229+ if ( this . isOpen ) {
230+ setTimeout ( ( ) => {
231+ this . updateListboxPosition ( ) ;
232+ } , 0 ) ;
233+ }
227234 }
228235
229236 private handleInputChange = ( event : Event ) => {
@@ -362,6 +369,11 @@ export class Combobox {
362369
363370 // Then update position in next frame
364371 requestAnimationFrame ( ( ) => {
372+ // Check elements still exist and are connected to DOM
373+ if ( ! this . comboEl || ! this . listboxPadEl || ! this . isOpen ) {
374+ return ;
375+ }
376+
365377 // Use floating-ui to compute the best position, accounting for scroll
366378 // The flip middleware will automatically switch to 'top' placement if there's not enough space below
367379 computePosition ( this . comboEl , this . listboxPadEl , {
@@ -373,6 +385,11 @@ export class Combobox {
373385 } ) ,
374386 ] ,
375387 } ) . then ( ( { x, y } ) => {
388+ // Final check before applying styles
389+ if ( ! this . listboxPadEl || ! this . comboEl || ! this . isOpen ) {
390+ return ;
391+ }
392+
376393 // Get fresh input rect for final positioning
377394 const freshInputRect = this . comboEl . getBoundingClientRect ( ) ;
378395 const freshInputWidth = freshInputRect . width ;
0 commit comments