diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index 3b4ef84f26f..f0416c69abf 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -310,19 +310,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( `.select-interface-option:nth-child(${indexOfSelected + 1})` @@ -345,6 +336,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(); @@ -372,8 +364,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; } diff --git a/core/src/components/select/test/basic/index.html b/core/src/components/select/test/basic/index.html index c958d08f909..4e70f5a2603 100644 --- a/core/src/components/select/test/basic/index.html +++ b/core/src/components/select/test/basic/index.html @@ -61,6 +61,169 @@ + + + Single Value - Overflowing Options + + + + + Apple + Apricot + Avocado + Banana + Blackberry + Blueberry + Cantaloupe + Cherry + Coconut + Cranberry + Dragonfruit + Fig + Grape + Grapefruit + Guava + Kiwi + Lemon + Lime + Lychee + Mango + Nectarine + Orange + Papaya + Passion Fruit + Peach + Pear + Pineapple + Plum + Pomegranate + Raspberry + Strawberry + Tangerine + Watermelon + + + + + + Apple + Apricot + Avocado + Banana + Blackberry + Blueberry + Cantaloupe + Cherry + Coconut + Cranberry + Dragonfruit + Fig + Grape + Grapefruit + Guava + Kiwi + Lemon + Lime + Lychee + Mango + Nectarine + Orange + Papaya + Passion Fruit + Peach + Pear + Pineapple + Plum + Pomegranate + Raspberry + Strawberry + Tangerine + Watermelon + + + + + + Apple + Apricot + Avocado + Banana + Blackberry + Blueberry + Cantaloupe + Cherry + Coconut + Cranberry + Dragonfruit + Fig + Grape + Grapefruit + Guava + Kiwi + Lemon + Lime + Lychee + Mango + Nectarine + Orange + Papaya + Passion Fruit + Peach + Pear + Pineapple + Plum + Pomegranate + Raspberry + Strawberry + Tangerine + Watermelon + + + + + + Apple + Apricot + Avocado + Banana + Blackberry + Blueberry + Cantaloupe + Cherry + Coconut + Cranberry + Dragonfruit + Fig + Grape + Grapefruit + Guava + Kiwi + Lemon + Lime + Lychee + Mango + Nectarine + Orange + Papaya + Passion Fruit + Peach + Pear + Pineapple + Plum + Pomegranate + Raspberry + Strawberry + Tangerine + Watermelon + + + + Multiple Value Select diff --git a/core/src/components/select/test/basic/select.e2e.ts b/core/src/components/select/test/basic/select.e2e.ts index 35747728495..c04899fe92c 100644 --- a/core/src/components/select/test/basic/select.e2e.ts +++ b/core/src/components/select/test/basic/select.e2e.ts @@ -8,7 +8,7 @@ import type { E2ELocator } from '@utils/test/playwright'; * does not. The overlay rendering is already tested in the respective * test files. */ -configs({ directions: ['ltr'] }).forEach(({ title, config }) => { +configs({ directions: ['ltr'] }).forEach(({ title, config, screenshot }) => { test.describe(title('select: basic'), () => { test.beforeEach(async ({ page }) => { await page.goto('/src/components/select/test/basic', config); @@ -24,6 +24,16 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => { await expect(page.locator('ion-alert')).toBeVisible(); }); + + test('it should scroll to selected option when opened', async ({ page }) => { + const ionAlertDidPresent = await page.spyOnEvent('ionAlertDidPresent'); + + await page.click('#alert-select-scroll-to-selected'); + await ionAlertDidPresent.next(); + + const alert = page.locator('ion-alert'); + await expect(alert).toHaveScreenshot(screenshot(`select-basic-alert-scroll-to-selected`)); + }); }); test.describe('select: action sheet', () => { @@ -36,6 +46,16 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => { await expect(page.locator('ion-action-sheet')).toBeVisible(); }); + + test('it should scroll to selected option when opened', async ({ page }) => { + const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent'); + + await page.click('#action-sheet-select-scroll-to-selected'); + await ionActionSheetDidPresent.next(); + + const actionSheet = page.locator('ion-action-sheet'); + await expect(actionSheet).toHaveScreenshot(screenshot(`select-basic-action-sheet-scroll-to-selected`)); + }); }); test.describe('select: popover', () => { @@ -57,6 +77,16 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => { await expect(popover).toBeVisible(); }); + + test('it should scroll to selected option when opened', async ({ page }) => { + const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent'); + + await page.click('#popover-select-scroll-to-selected'); + await ionPopoverDidPresent.next(); + + const popover = page.locator('ion-popover'); + await expect(popover).toHaveScreenshot(screenshot(`select-basic-popover-scroll-to-selected`)); + }); }); test.describe('select: modal', () => { @@ -75,6 +105,16 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => { await expect(modal).toBeVisible(); }); + + test('it should scroll to selected option when opened', async ({ page }) => { + const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); + + await page.click('#modal-select-scroll-to-selected'); + await ionModalDidPresent.next(); + + const modal = page.locator('ion-modal'); + await expect(modal).toHaveScreenshot(screenshot(`select-basic-modal-scroll-to-selected`)); + }); }); }); }); diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png new file mode 100644 index 00000000000..3ce1c62f766 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png new file mode 100644 index 00000000000..b55a80fa526 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png new file mode 100644 index 00000000000..ccbd6b826b0 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png new file mode 100644 index 00000000000..2067ad9a95c Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png new file mode 100644 index 00000000000..b2753efbf69 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-md-ltr-Mobile-Safari-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-md-ltr-Mobile-Safari-linux.png new file mode 100644 index 00000000000..48a56e08b4c Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-action-sheet-scroll-to-selected-md-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png new file mode 100644 index 00000000000..7c3fe544430 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png new file mode 100644 index 00000000000..3394b979256 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png new file mode 100644 index 00000000000..cdbac490862 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png new file mode 100644 index 00000000000..8180a337a68 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png new file mode 100644 index 00000000000..a85cc6a5d4a Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-md-ltr-Mobile-Safari-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-md-ltr-Mobile-Safari-linux.png new file mode 100644 index 00000000000..4ef64e79c01 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-alert-scroll-to-selected-md-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png new file mode 100644 index 00000000000..926a1dc6bbf Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png new file mode 100644 index 00000000000..2e4f0b3a06f Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png new file mode 100644 index 00000000000..aff717eb1cd Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png new file mode 100644 index 00000000000..72e6b4bfe6e Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png new file mode 100644 index 00000000000..96561b7dad8 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-md-ltr-Mobile-Safari-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-md-ltr-Mobile-Safari-linux.png new file mode 100644 index 00000000000..510790f0cdc Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-modal-scroll-to-selected-md-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png new file mode 100644 index 00000000000..a018bd0ebb2 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-ios-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png new file mode 100644 index 00000000000..f6dda21ddea Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-ios-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png new file mode 100644 index 00000000000..aa391bdc5c6 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-ios-ltr-Mobile-Safari-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png new file mode 100644 index 00000000000..a4878d821da Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-md-ltr-Mobile-Chrome-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png new file mode 100644 index 00000000000..9a6b6a34ed4 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-md-ltr-Mobile-Firefox-linux.png differ diff --git a/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-md-ltr-Mobile-Safari-linux.png b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-md-ltr-Mobile-Safari-linux.png new file mode 100644 index 00000000000..597038e9c67 Binary files /dev/null and b/core/src/components/select/test/basic/select.e2e.ts-snapshots/select-basic-popover-scroll-to-selected-md-ltr-Mobile-Safari-linux.png differ