diff --git a/src/components/select/select.ts b/src/components/select/select.ts index 7f3c7780c..bbbb4e364 100644 --- a/src/components/select/select.ts +++ b/src/components/select/select.ts @@ -472,6 +472,9 @@ export default class SlSelect extends ShoelaceElement implements ShoelaceFormCon } if (this.open) { + const selectedOption = this.getOptionByValue(this.value); + const currentOption = selectedOption || this.getFirstOption(); + // Show this.emit('sl-show'); this.addOpenListeners(); @@ -480,25 +483,20 @@ export default class SlSelect extends ShoelaceElement implements ShoelaceFormCon this.listbox.hidden = false; this.popup.active = true; + // Select the appropriate option based on value after the listbox opens requestAnimationFrame(() => { - // Select the appropriate option based on value after the listbox opens - const selectedOption = this.getOptionByValue(this.value); - const currentOption = selectedOption || this.getFirstOption(); this.setSelectedOption(selectedOption); this.setCurrentOption(currentOption); - - // Scroll to the selected option - if (currentOption) { - // - // TODO - improve this logic so the selected option is centered in the listbox instead of at the top - // - this.listbox.scrollTop = currentOption.offsetTop; - } }); const { keyframes, options } = getAnimation(this, 'select.show', { dir: this.localize.dir() }); await animateTo(this.popup.popup, keyframes, options); + // Make sure the current option is scrolled into view (required for Safari) + if (currentOption) { + scrollIntoView(currentOption, this.listbox, 'vertical', 'auto'); + } + this.emit('sl-after-show'); } else { // Hide diff --git a/src/internal/scroll.ts b/src/internal/scroll.ts index 356c1fb46..89e994bae 100644 --- a/src/internal/scroll.ts +++ b/src/internal/scroll.ts @@ -22,9 +22,7 @@ export function unlockBodyScrolling(lockingEl: HTMLElement) { } } -/** - * Scrolls an element into view of its container. If the element is already in view, nothing will happen. - */ +/** Scrolls an element into view of its container. If the element is already in view, nothing will happen. */ export function scrollIntoView( element: HTMLElement, container: HTMLElement,