Skip to content

Commit b66fe53

Browse files
fix: improve listbox positioning and event handling in combobox component
1 parent 4af7fb0 commit b66fe53

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

packages/components/src/components/combobox/combobox.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)