Merge branch 'main' of github.com:ionic-team/ionic-framework into merge/main-into-8.5

This commit is contained in:
ShaneK
2025-03-03 05:44:37 -08:00
33 changed files with 332 additions and 29 deletions

View File

@@ -317,19 +317,10 @@ export class Select implements ComponentInterface {
}
this.isExpanded = true;
const overlay = (this.overlay = await this.createOverlay(event));
overlay.onDidDismiss().then(() => {
this.overlay = undefined;
this.isExpanded = false;
this.ionDismiss.emit();
this.setFocus();
});
await overlay.present();
// focus selected option for popovers and modals
if (this.interface === 'popover' || this.interface === 'modal') {
// Add logic to scroll selected item into view before presenting
const scrollSelectedIntoView = () => {
const indexOfSelected = this.childOpts.findIndex((o) => o.value === this.value);
if (indexOfSelected > -1) {
const selectedItem = overlay.querySelector<HTMLElement>(
`.select-interface-option:nth-child(${indexOfSelected + 1})`
@@ -352,6 +343,7 @@ export class Select implements ComponentInterface {
| HTMLIonCheckboxElement
| null;
if (interactiveEl) {
selectedItem.scrollIntoView({ block: 'nearest' });
// Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
// and removing `ion-focused` style
interactiveEl.setFocus();
@@ -379,8 +371,40 @@ export class Select implements ComponentInterface {
focusVisibleElement(firstEnabledOption.closest('ion-item')!);
}
}
};
// For modals and popovers, we can scroll before they're visible
if (this.interface === 'modal') {
overlay.addEventListener('ionModalWillPresent', scrollSelectedIntoView, { once: true });
} else if (this.interface === 'popover') {
overlay.addEventListener('ionPopoverWillPresent', scrollSelectedIntoView, { once: true });
} else {
/**
* For alerts and action sheets, we need to wait a frame after willPresent
* because these overlays don't have their content in the DOM immediately
* when willPresent fires. By waiting a frame, we ensure the content is
* rendered and can be properly scrolled into view.
*/
const scrollAfterRender = () => {
requestAnimationFrame(() => {
scrollSelectedIntoView();
});
};
if (this.interface === 'alert') {
overlay.addEventListener('ionAlertWillPresent', scrollAfterRender, { once: true });
} else if (this.interface === 'action-sheet') {
overlay.addEventListener('ionActionSheetWillPresent', scrollAfterRender, { once: true });
}
}
overlay.onDidDismiss().then(() => {
this.overlay = undefined;
this.isExpanded = false;
this.ionDismiss.emit();
this.setFocus();
});
await overlay.present();
return overlay;
}