From 7b32820771a942e159ab02c443ee05b18286c4e2 Mon Sep 17 00:00:00 2001 From: Tanner Reits <47483144+tanner-reits@users.noreply.github.com> Date: Thu, 31 Oct 2024 10:01:32 -0400 Subject: [PATCH] feat(select): add `modal` as interface (#29972) Issue number: resolves internal --------- ## What is the current behavior? Select only offers `alert`, `action-sheet`, and `popover` as interfaces ## What is the new behavior? Adds `modal` as an interface option for `ion-select` ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information --------- Co-authored-by: Brandy Carney --- core/api.txt | 7 +- core/src/components.d.ts | 32 +++- core/src/components/checkbox/checkbox.tsx | 6 +- .../components/radio-group/radio-group.tsx | 6 +- core/src/components/radio/radio.tsx | 8 +- .../select-modal/select-modal-interface.ts | 8 + .../select-modal/select-modal.ios.scss | 1 + .../select-modal/select-modal.md.scss | 30 ++++ .../components/select-modal/select-modal.scss | 3 + .../components/select-modal/select-modal.tsx | 161 ++++++++++++++++++ .../select-modal/test/basic/index.html | 40 +++++ .../test/basic/select-modal.e2e.ts | 101 +++++++++++ ...modal-diff-ios-ltr-Mobile-Chrome-linux.png | Bin 0 -> 5626 bytes ...odal-diff-ios-ltr-Mobile-Firefox-linux.png | Bin 0 -> 11684 bytes ...modal-diff-ios-ltr-Mobile-Safari-linux.png | Bin 0 -> 5427 bytes ...-modal-diff-md-ltr-Mobile-Chrome-linux.png | Bin 0 -> 5474 bytes ...modal-diff-md-ltr-Mobile-Firefox-linux.png | Bin 0 -> 11170 bytes ...-modal-diff-md-ltr-Mobile-Safari-linux.png | Bin 0 -> 5090 bytes ...tiple-diff-ios-ltr-Mobile-Chrome-linux.png | Bin 0 -> 6759 bytes ...iple-diff-ios-ltr-Mobile-Firefox-linux.png | Bin 0 -> 12959 bytes ...tiple-diff-ios-ltr-Mobile-Safari-linux.png | Bin 0 -> 6608 bytes ...ltiple-diff-md-ltr-Mobile-Chrome-linux.png | Bin 0 -> 5918 bytes ...tiple-diff-md-ltr-Mobile-Firefox-linux.png | Bin 0 -> 11793 bytes ...ltiple-diff-md-ltr-Mobile-Safari-linux.png | Bin 0 -> 5564 bytes .../components/select-modal/test/fixtures.ts | 73 ++++++++ .../src/components/select/select-interface.ts | 2 +- core/src/components/select/select.tsx | 89 ++++++++-- .../components/select/test/basic/index.html | 35 ++++ .../select/test/basic/select.e2e.ts | 18 ++ core/src/utils/overlays-interface.ts | 6 +- .../angular/src/directives/proxies-list.ts | 1 + packages/angular/src/directives/proxies.ts | 22 +++ .../standalone/src/directives/proxies.ts | 25 +++ packages/react/src/components/proxies.ts | 2 + packages/vue/src/proxies.ts | 8 + 35 files changed, 651 insertions(+), 33 deletions(-) create mode 100644 core/src/components/select-modal/select-modal-interface.ts create mode 100644 core/src/components/select-modal/select-modal.ios.scss create mode 100644 core/src/components/select-modal/select-modal.md.scss create mode 100644 core/src/components/select-modal/select-modal.scss create mode 100644 core/src/components/select-modal/select-modal.tsx create mode 100644 core/src/components/select-modal/test/basic/index.html create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-ios-ltr-Mobile-Chrome-linux.png create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-ios-ltr-Mobile-Firefox-linux.png create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-ios-ltr-Mobile-Safari-linux.png create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-md-ltr-Mobile-Chrome-linux.png create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-md-ltr-Mobile-Firefox-linux.png create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-md-ltr-Mobile-Safari-linux.png create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-ios-ltr-Mobile-Chrome-linux.png create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-ios-ltr-Mobile-Firefox-linux.png create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-ios-ltr-Mobile-Safari-linux.png create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-md-ltr-Mobile-Chrome-linux.png create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-md-ltr-Mobile-Firefox-linux.png create mode 100644 core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-md-ltr-Mobile-Safari-linux.png create mode 100644 core/src/components/select-modal/test/fixtures.ts diff --git a/core/api.txt b/core/api.txt index de7c3531974..3aff52a1cfc 100644 --- a/core/api.txt +++ b/core/api.txt @@ -1614,7 +1614,7 @@ ion-select,prop,compareWith,((currentValue: any, compareValue: any) => boolean) ion-select,prop,disabled,boolean,false,false,false ion-select,prop,expandedIcon,string | undefined,undefined,false,false ion-select,prop,fill,"outline" | "solid" | undefined,undefined,false,false -ion-select,prop,interface,"action-sheet" | "alert" | "popover",'alert',false,false +ion-select,prop,interface,"action-sheet" | "alert" | "modal" | "popover",'alert',false,false ion-select,prop,interfaceOptions,any,{},false,false ion-select,prop,justify,"end" | "space-between" | "start" | undefined,undefined,false,false ion-select,prop,label,string | undefined,undefined,false,false @@ -1672,6 +1672,11 @@ ion-select,part,label ion-select,part,placeholder ion-select,part,text +ion-select-modal,scoped +ion-select-modal,prop,header,string | undefined,undefined,false,false +ion-select-modal,prop,multiple,boolean | undefined,undefined,false,false +ion-select-modal,prop,options,SelectModalOption[],[],false,false + ion-select-option,shadow ion-select-option,prop,disabled,boolean,false,false,false ion-select-option,prop,value,any,undefined,false,false diff --git a/core/src/components.d.ts b/core/src/components.d.ts index f0cd3d081ad..48ceedfa8a1 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -35,6 +35,7 @@ import { SearchbarChangeEventDetail, SearchbarInputEventDetail } from "./compone import { SegmentChangeEventDetail, SegmentValue } from "./components/segment/segment-interface"; import { SegmentButtonLayout } from "./components/segment-button/segment-button-interface"; import { SelectChangeEventDetail, SelectCompareFn, SelectInterface } from "./components/select/select-interface"; +import { SelectModalOption } from "./components/select-modal/select-modal-interface"; import { SelectPopoverOption } from "./components/select-popover/select-popover-interface"; import { TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout } from "./components/tab-bar/tab-bar-interface"; import { TextareaChangeEventDetail, TextareaInputEventDetail } from "./components/textarea/textarea-interface"; @@ -70,6 +71,7 @@ export { SearchbarChangeEventDetail, SearchbarInputEventDetail } from "./compone export { SegmentChangeEventDetail, SegmentValue } from "./components/segment/segment-interface"; export { SegmentButtonLayout } from "./components/segment-button/segment-button-interface"; export { SelectChangeEventDetail, SelectCompareFn, SelectInterface } from "./components/select/select-interface"; +export { SelectModalOption } from "./components/select-modal/select-modal-interface"; export { SelectPopoverOption } from "./components/select-popover/select-popover-interface"; export { TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout } from "./components/tab-bar/tab-bar-interface"; export { TextareaChangeEventDetail, TextareaInputEventDetail } from "./components/textarea/textarea-interface"; @@ -639,6 +641,7 @@ export namespace Components { * The name of the control, which is submitted with the form data. */ "name": string; + "setFocus": () => Promise; /** * The value of the checkbox does not mean if it's checked or not, use the `checked` property for that. The value of a checkbox is analogous to the value of an ``, it's only used when the checkbox participates in a native `
`. */ @@ -2279,7 +2282,7 @@ export namespace Components { */ "name": string; "setButtonTabindex": (value: number) => Promise; - "setFocus": (ev: globalThis.Event) => Promise; + "setFocus": (ev?: globalThis.Event) => Promise; /** * the value of the radio. */ @@ -2741,11 +2744,11 @@ export namespace Components { */ "fill"?: 'outline' | 'solid'; /** - * The interface the select should use: `action-sheet`, `popover` or `alert`. + * The interface the select should use: `action-sheet`, `popover`, `alert`, or `modal`. */ "interface": SelectInterface; /** - * Any additional options that the `alert`, `action-sheet` or `popover` interface can take. See the [ion-alert docs](./alert), the [ion-action-sheet docs](./action-sheet) and the [ion-popover docs](./popover) for the create options for each interface. Note: `interfaceOptions` will not override `inputs` or `buttons` with the `alert` interface. + * Any additional options that the `alert`, `action-sheet` or `popover` interface can take. See the [ion-alert docs](./alert), the [ion-action-sheet docs](./action-sheet), the [ion-popover docs](./popover), and the [ion-modal docs](./modal) for the create options for each interface. Note: `interfaceOptions` will not override `inputs` or `buttons` with the `alert` interface. */ "interfaceOptions": any; /** @@ -2802,6 +2805,11 @@ export namespace Components { */ "value"?: any | null; } + interface IonSelectModal { + "header"?: string; + "multiple"?: boolean; + "options": SelectModalOption[]; + } interface IonSelectOption { /** * If `true`, the user cannot interact with the select option. This property does not apply when `interface="action-sheet"` as `ion-action-sheet` does not allow for disabled buttons. @@ -4434,6 +4442,12 @@ declare global { prototype: HTMLIonSelectElement; new (): HTMLIonSelectElement; }; + interface HTMLIonSelectModalElement extends Components.IonSelectModal, HTMLStencilElement { + } + var HTMLIonSelectModalElement: { + prototype: HTMLIonSelectModalElement; + new (): HTMLIonSelectModalElement; + }; interface HTMLIonSelectOptionElement extends Components.IonSelectOption, HTMLStencilElement { } var HTMLIonSelectOptionElement: { @@ -4722,6 +4736,7 @@ declare global { "ion-segment": HTMLIonSegmentElement; "ion-segment-button": HTMLIonSegmentButtonElement; "ion-select": HTMLIonSelectElement; + "ion-select-modal": HTMLIonSelectModalElement; "ion-select-option": HTMLIonSelectOptionElement; "ion-select-popover": HTMLIonSelectPopoverElement; "ion-skeleton-text": HTMLIonSkeletonTextElement; @@ -7497,11 +7512,11 @@ declare namespace LocalJSX { */ "fill"?: 'outline' | 'solid'; /** - * The interface the select should use: `action-sheet`, `popover` or `alert`. + * The interface the select should use: `action-sheet`, `popover`, `alert`, or `modal`. */ "interface"?: SelectInterface; /** - * Any additional options that the `alert`, `action-sheet` or `popover` interface can take. See the [ion-alert docs](./alert), the [ion-action-sheet docs](./action-sheet) and the [ion-popover docs](./popover) for the create options for each interface. Note: `interfaceOptions` will not override `inputs` or `buttons` with the `alert` interface. + * Any additional options that the `alert`, `action-sheet` or `popover` interface can take. See the [ion-alert docs](./alert), the [ion-action-sheet docs](./action-sheet), the [ion-popover docs](./popover), and the [ion-modal docs](./modal) for the create options for each interface. Note: `interfaceOptions` will not override `inputs` or `buttons` with the `alert` interface. */ "interfaceOptions"?: any; /** @@ -7577,6 +7592,11 @@ declare namespace LocalJSX { */ "value"?: any | null; } + interface IonSelectModal { + "header"?: string; + "multiple"?: boolean; + "options"?: SelectModalOption[]; + } interface IonSelectOption { /** * If `true`, the user cannot interact with the select option. This property does not apply when `interface="action-sheet"` as `ion-action-sheet` does not allow for disabled buttons. @@ -8163,6 +8183,7 @@ declare namespace LocalJSX { "ion-segment": IonSegment; "ion-segment-button": IonSegmentButton; "ion-select": IonSelect; + "ion-select-modal": IonSelectModal; "ion-select-option": IonSelectOption; "ion-select-popover": IonSelectPopover; "ion-skeleton-text": IonSkeletonText; @@ -8262,6 +8283,7 @@ declare module "@stencil/core" { "ion-segment": LocalJSX.IonSegment & JSXBase.HTMLAttributes; "ion-segment-button": LocalJSX.IonSegmentButton & JSXBase.HTMLAttributes; "ion-select": LocalJSX.IonSelect & JSXBase.HTMLAttributes; + "ion-select-modal": LocalJSX.IonSelectModal & JSXBase.HTMLAttributes; "ion-select-option": LocalJSX.IonSelectOption & JSXBase.HTMLAttributes; "ion-select-popover": LocalJSX.IonSelectPopover & JSXBase.HTMLAttributes; "ion-skeleton-text": LocalJSX.IonSkeletonText & JSXBase.HTMLAttributes; diff --git a/core/src/components/checkbox/checkbox.tsx b/core/src/components/checkbox/checkbox.tsx index 1eca97eeda7..78206b9fd16 100644 --- a/core/src/components/checkbox/checkbox.tsx +++ b/core/src/components/checkbox/checkbox.tsx @@ -1,5 +1,5 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core'; -import { Component, Element, Event, Host, Prop, h } from '@stencil/core'; +import { Component, Element, Event, Host, Method, Prop, h } from '@stencil/core'; import type { Attributes } from '@utils/helpers'; import { inheritAriaAttributes, renderHiddenInput } from '@utils/helpers'; import { createColorClasses, hostContext } from '@utils/theme'; @@ -121,7 +121,9 @@ export class Checkbox implements ComponentInterface { }; } - private setFocus() { + /** @internal */ + @Method() + async setFocus() { if (this.focusEl) { this.focusEl.focus(); } diff --git a/core/src/components/radio-group/radio-group.tsx b/core/src/components/radio-group/radio-group.tsx index c46156a2c95..5d6036bc842 100644 --- a/core/src/components/radio-group/radio-group.tsx +++ b/core/src/components/radio-group/radio-group.tsx @@ -155,7 +155,9 @@ export class RadioGroup implements ComponentInterface { @Listen('keydown', { target: 'document' }) onKeydown(ev: KeyboardEvent) { - const inSelectPopover = !!this.el.closest('ion-select-popover'); + // We don't want the value to automatically change/emit when the radio group is part of a select interface + // as this will cause the interface to close when navigating through the radio group options + const inSelectInterface = !!this.el.closest('ion-select-popover') || !!this.el.closest('ion-select-modal'); if (ev.target && !this.el.contains(ev.target as HTMLElement)) { return; @@ -187,7 +189,7 @@ export class RadioGroup implements ComponentInterface { if (next && radios.includes(next)) { next.setFocus(ev); - if (!inSelectPopover) { + if (!inSelectInterface) { this.value = next.value; this.emitValueChange(ev); } diff --git a/core/src/components/radio/radio.tsx b/core/src/components/radio/radio.tsx index e037d110f95..bb343c8c858 100644 --- a/core/src/components/radio/radio.tsx +++ b/core/src/components/radio/radio.tsx @@ -126,9 +126,11 @@ export class Radio implements ComponentInterface { /** @internal */ @Method() - async setFocus(ev: globalThis.Event) { - ev.stopPropagation(); - ev.preventDefault(); + async setFocus(ev?: globalThis.Event) { + if (ev !== undefined) { + ev.stopPropagation(); + ev.preventDefault(); + } this.el.focus(); } diff --git a/core/src/components/select-modal/select-modal-interface.ts b/core/src/components/select-modal/select-modal-interface.ts new file mode 100644 index 00000000000..2005400cb82 --- /dev/null +++ b/core/src/components/select-modal/select-modal-interface.ts @@ -0,0 +1,8 @@ +export interface SelectModalOption { + text: string; + value: string; + disabled: boolean; + checked: boolean; + cssClass?: string | string[]; + handler?: (value: any) => boolean | void | { [key: string]: any }; +} diff --git a/core/src/components/select-modal/select-modal.ios.scss b/core/src/components/select-modal/select-modal.ios.scss new file mode 100644 index 00000000000..7e60b693fcf --- /dev/null +++ b/core/src/components/select-modal/select-modal.ios.scss @@ -0,0 +1 @@ +@import "./select-modal"; diff --git a/core/src/components/select-modal/select-modal.md.scss b/core/src/components/select-modal/select-modal.md.scss new file mode 100644 index 00000000000..511c8d786ab --- /dev/null +++ b/core/src/components/select-modal/select-modal.md.scss @@ -0,0 +1,30 @@ +@import "./select-modal"; +@import "../../themes/ionic.mixins.scss"; +@import "../item/item.md.vars"; + +ion-list ion-radio::part(container) { + display: none; +} + +ion-list ion-radio::part(label) { + @include margin(0); +} + +ion-item { + --inner-border-width: 0; +} + +.item-radio-checked { + --background: #{ion-color(primary, base, 0.08)}; + --background-focused: #{ion-color(primary, base)}; + --background-focused-opacity: 0.2; + --background-hover: #{ion-color(primary, base)}; + --background-hover-opacity: 0.12; +} + +.item-checkbox-checked { + --background-activated: #{$item-md-color}; + --background-focused: #{$item-md-color}; + --background-hover: #{$item-md-color}; + --color: #{ion-color(primary, base)}; +} diff --git a/core/src/components/select-modal/select-modal.scss b/core/src/components/select-modal/select-modal.scss new file mode 100644 index 00000000000..683ae23faeb --- /dev/null +++ b/core/src/components/select-modal/select-modal.scss @@ -0,0 +1,3 @@ +:host { + height: 100%; +} diff --git a/core/src/components/select-modal/select-modal.tsx b/core/src/components/select-modal/select-modal.tsx new file mode 100644 index 00000000000..ad927860439 --- /dev/null +++ b/core/src/components/select-modal/select-modal.tsx @@ -0,0 +1,161 @@ +import { getIonMode } from '@global/ionic-global'; +import type { ComponentInterface } from '@stencil/core'; +import { Component, Element, Host, Prop, forceUpdate, h } from '@stencil/core'; +import { safeCall } from '@utils/overlays'; +import { getClassMap } from '@utils/theme'; + +import type { CheckboxCustomEvent } from '../checkbox/checkbox-interface'; +import type { RadioGroupCustomEvent } from '../radio-group/radio-group-interface'; + +import type { SelectModalOption } from './select-modal-interface'; + +@Component({ + tag: 'ion-select-modal', + styleUrls: { + ios: 'select-modal.ios.scss', + md: 'select-modal.md.scss', + ionic: 'select-modal.md.scss', + }, + scoped: true, +}) +export class SelectModal implements ComponentInterface { + @Element() el!: HTMLIonSelectModalElement; + + @Prop() header?: string; + + @Prop() multiple?: boolean; + + @Prop() options: SelectModalOption[] = []; + + private closeModal() { + const modal = this.el.closest('ion-modal'); + + if (modal) { + modal.dismiss(); + } + } + + private findOptionFromEvent(ev: CheckboxCustomEvent | RadioGroupCustomEvent) { + const { options } = this; + return options.find((o) => o.value === ev.target.value); + } + + private getValues(ev?: CheckboxCustomEvent | RadioGroupCustomEvent): string | string[] | undefined { + const { multiple, options } = this; + + if (multiple) { + // this is a modal with checkboxes (multiple value select) + // return an array of all the checked values + return options.filter((o) => o.checked).map((o) => o.value); + } + + // this is a modal with radio buttons (single value select) + // return the value that was clicked, otherwise undefined + const option = ev ? this.findOptionFromEvent(ev) : null; + return option ? option.value : undefined; + } + + private callOptionHandler(ev: CheckboxCustomEvent | RadioGroupCustomEvent) { + const option = this.findOptionFromEvent(ev); + const values = this.getValues(ev); + if (option?.handler) { + safeCall(option.handler, values); + } + } + + private setChecked(ev: CheckboxCustomEvent): void { + const { multiple } = this; + const option = this.findOptionFromEvent(ev); + + // this is a modal with checkboxes (multiple value select) + // we need to set the checked value for this option + if (multiple && option) { + option.checked = ev.detail.checked; + } + } + + private renderRadioOptions() { + const checked = this.options.filter((o) => o.checked).map((o) => o.value)[0]; + + return ( + this.callOptionHandler(ev)}> + {this.options.map((option) => ( + + this.closeModal()} + onKeyUp={(ev) => { + if (ev.key === ' ') { + /** + * Selecting a radio option with keyboard navigation, + * either through the Enter or Space keys, should + * dismiss the modal. + */ + this.closeModal(); + } + }} + > + {option.text} + + + ))} + + ); + } + + private renderCheckboxOptions() { + return this.options.map((option) => ( + + { + this.setChecked(ev); + this.callOptionHandler(ev); + // TODO FW-4784 + forceUpdate(this); + }} + > + {option.text} + + + )); + } + + render() { + return ( + + + + {this.header !== undefined && {this.header}} + + + this.closeModal()}>Close + + + + + {this.multiple === true ? this.renderCheckboxOptions() : this.renderRadioOptions()} + + + ); + } +} diff --git a/core/src/components/select-modal/test/basic/index.html b/core/src/components/select-modal/test/basic/index.html new file mode 100644 index 00000000000..8ddb3b54f0b --- /dev/null +++ b/core/src/components/select-modal/test/basic/index.html @@ -0,0 +1,40 @@ + + + + + Select - Modal + + + + + + + + + + + + + Select Modal - Basic + + + + + + + + + + + + + diff --git a/core/src/components/select-modal/test/basic/select-modal.e2e.ts b/core/src/components/select-modal/test/basic/select-modal.e2e.ts new file mode 100644 index 00000000000..126082712c3 --- /dev/null +++ b/core/src/components/select-modal/test/basic/select-modal.e2e.ts @@ -0,0 +1,101 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +import type { SelectModalOption } from '../../select-modal-interface'; +import { SelectModalPage } from '../fixtures'; + +const options: SelectModalOption[] = [ + { value: 'apple', text: 'Apple', disabled: false, checked: false }, + { value: 'banana', text: 'Banana', disabled: false, checked: false }, +]; + +const checkedOptions: SelectModalOption[] = [ + { value: 'apple', text: 'Apple', disabled: false, checked: true }, + { value: 'banana', text: 'Banana', disabled: false, checked: false }, +]; + +/** + * This behavior does not vary across modes/directions. + */ +configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('select-modal: basic'), () => { + test.beforeEach(({ browserName }) => { + test.skip(browserName === 'webkit', 'ROU-5437'); + }); + + test.describe('single selection', () => { + let selectModalPage: SelectModalPage; + + test.beforeEach(async ({ page }) => { + selectModalPage = new SelectModalPage(page); + }); + + test('clicking an unselected option should dismiss the modal', async () => { + await selectModalPage.setup(config, options, false); + + await selectModalPage.clickOption('apple'); + await selectModalPage.ionModalDidDismiss.next(); + await expect(selectModalPage.modal).not.toBeVisible(); + }); + + test('clicking a selected option should dismiss the modal', async () => { + await selectModalPage.setup(config, checkedOptions, false); + + await selectModalPage.clickOption('apple'); + await selectModalPage.ionModalDidDismiss.next(); + await expect(selectModalPage.modal).not.toBeVisible(); + }); + + test('pressing Space on an unselected option should dismiss the modal', async () => { + await selectModalPage.setup(config, options, false); + + await selectModalPage.pressSpaceOnOption('apple'); + await selectModalPage.ionModalDidDismiss.next(); + await expect(selectModalPage.modal).not.toBeVisible(); + }); + + test('pressing Space on a selected option should dismiss the modal', async ({ browserName }) => { + test.skip(browserName === 'firefox', 'Same behavior as ROU-5437'); + + await selectModalPage.setup(config, checkedOptions, false); + + await selectModalPage.pressSpaceOnOption('apple'); + await selectModalPage.ionModalDidDismiss.next(); + await expect(selectModalPage.modal).not.toBeVisible(); + }); + + test('clicking the close button should dismiss the modal', async () => { + await selectModalPage.setup(config, options, false); + + const closeButton = selectModalPage.modal.locator('ion-header ion-toolbar ion-button'); + await closeButton.click(); + await selectModalPage.ionModalDidDismiss.next(); + await expect(selectModalPage.modal).not.toBeVisible(); + }); + }); + }); +}); + +/** + * This behavior does not vary across directions. + * The components used inside of `ion-select-modal` + * do have RTL logic, but those are tested in their + * respective component test files. + */ +configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { + test.describe(title('select-modal: rendering'), () => { + let selectModalPage: SelectModalPage; + + test.beforeEach(async ({ page }) => { + selectModalPage = new SelectModalPage(page); + }); + test('should not have visual regressions with single selection', async () => { + await selectModalPage.setup(config, checkedOptions, false); + await selectModalPage.screenshot(screenshot, 'select-modal-diff'); + }); + test('should not have visual regressions with multiple selection', async () => { + await selectModalPage.setup(config, checkedOptions, true); + await selectModalPage.screenshot(screenshot, 'select-modal-multiple-diff'); + }); + }); +}); diff --git a/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-ios-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..72f5453ea82e5a783286f860ae0d9ff4df6c4881 GIT binary patch literal 5626 zcmeI0SyWTmn#Vz_q^l6T7Ah)(UAL=b5~77N$W#u9SONu#$QYGE1caz01PDnG2bw^E zRw-Bph)h9?BzKtGeOcYkeQU|`~Z@_2}WfnlD3!3OrfZ2+DqhaHxIn_+5*-%$f1({jPU zV0)AQ@grx`OT}Eoy>qiS1=3;eL2lHSuebX)wjcj0~ooI`${cdzdRS-Ro=7rFnLH@WSvwkJ}! z0ZNXf1ATD#$jnrY#oC=LZ!}HdDM=OH^y!2#7lvyIkFi+e?ENgiOhW_6QEc|{i7&nz z+WYVKT@3S@zB*YQ@Z(>TH++*|cJJi>eYI@!{vo$#*rMM9YY!RIgXp$g=}FPnh>>oY z+mNw=X@gO@ZFK9?^*dH-!ogYEA#nM)sNk+v@V$N|f2gS3PAmV?t7v{V|Mu!$x5vng zzRrFKWH;i*TX?)Y!ksjbLqH_+!xN}+10a`&MY17Yj!Sp2=#JGxkXIXIuDyB7pG#iJ zN5u;^>?~-An2xHDNEv7KtsPj?9~v9ZHWlk$y^BU)yEv8rjtowe2w!-#;cr!qCi{$q z**q;*RY`~M zDw?)Rj=9;tXacL?+#sXjliR?((?quR=VFN`oU z%q*KnQ|yZNob!SXT5LQBOqd&{RK42Y5Cu-5#z`8r^%6anr-uee%#6+jm9;A42gE*G zRT{0M(rZ-3>KEZ2v*URM6pyebo{UypSb>Asy6U(*W$DkWw?wKe_&JH!+gZC*rRF_S z34i^!@gNRCJEf*fpU!1&@o?Z%oo{#Xs?OCs zJxh~L&R;0k1T6fASrS1{`#LnVr$#VBjNf*8 z2HyF@he!3JA&toR+1ocmSM@JYKlAI+ngotMvrYbp7g|ypjTnxT-%@Xax^+ z4N6V5xT_s0iXJwE%+Zb!=*^Y#8n*qhP1Ge>g0^J^_{ktkc9qhwBx+-(IW2Ps2TofW z&nbb2B_?5JRAJkF-_>>|@(NU-KoUAFX}!C4qEms6aHU4YC|YSoGAChDzJ*gA4jByh z{%-cMX<>vOmN;-K7|Ls0`Z*Cqq>$HDzK*mQ@Nf0?(@2v;`M4}@`@pnKBm)=1t-{+j zn-^(bG)ZS~goa9a6)ZOL>C()Z#IOd4 zhsa|qSHwLvoD?cLD6Ej2%xM9-+85dKETnGo+AEXT-U9b)O^uC>wipRoueQP#c`42Z z1iUSS^VZW&)CS>n6cEDVEb=M?1%5%_>B0vpK+bG_y;XITNF%~{U@k?I|%0tm5Dca>chv2Ju982+YfCD@ppG0h* zn@A#w$IjS4#8js1)&&;3cT?I>Pei;ptWJpS7_f>~OIL*+FQMc5v2c5M(4*03;p9xY z(0Raf)q}qt$SCi=Wdw?7x}wvpH#e&x7sTUaL6;puvADpe>u+L>c8Lc`V0xwP9J94|^@Cvwv*G^q$&c3B{&RCDNs(uIaSKkY z9u4869v?sn&*1Da)0))*^xFH}=C6)I7uNB;*cgX;%q)24V8c(D##TZ5k)lYxeMvv3 zCE4TsZ8M&39-ArcF*n-0bFdY{Kh~Z&RkkoRuu#lTKTnWtVzF38{sY~9TcAV!HZTz- zJ7rKyC*OGbtEKzOYqOv%cvaV){1jc;_Ux3cD(ekXL8YItWBaiZuCdOsu?EAgoZGOB z;2ksg?nZ#or|$RuW^l9_rK?rqfR}R87(^YEw%6Au&JR{po%prBuFic(w850n=7OBD z;J3*~BSk_XrqcG|shW@lFG;%oR{yIQeokQqFR8bd<~GR%+MeiKcYvw3yQhpqmA-qE*R7 zWAtD8egn`i`foM?nW`0?d{#=e7O{*S}>1>zI&Z#mS6eE1HSa_<1Z~k@{$kh z)@CGaGld>YZLxsPoa336t|^m37QusljSFLQp~C@IIQZgNFc_?_0U_&R$$)dgB|Ly# z(O9W-d>|=?cB*Em;?c+6*ifKjs)*QecCfGi&!7zX&FQSct2s3|d7?OUto?#%|DW zIM65c_4N)U>Pm5BO2%@xQEgz^#Kc4Gs?f6OThGfTcmNV$*rjswP0+0a%w`t-VxJer~1Y?3DXsKx;fs zC#&@he$YP)OpAw7i`5D-);;xd@HQYY0)fy0BKZ+iIvsouRbU0|Esz`v+u Z_ueC-T+Uzcz+tX|zi;4i;?WB^{{@3BZ887= literal 0 HcmV?d00001 diff --git a/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-ios-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..b69898dc6dc76c73e4a0a63ae0bd8eb1160a5285 GIT binary patch literal 11684 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 C8L007 literal 0 HcmV?d00001 diff --git a/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-ios-ltr-Mobile-Safari-linux.png b/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-ios-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..05425333c5f209db3974534a77fbd7d7a50521d3 GIT binary patch literal 5427 zcmeHLX;70{)&}jCwiV(iJ+y4;Z-fR>Ktw@V?M9@5Mg&2Gu&A`G5=8bT#AOsk0TBTO zOaugE3!5xSNTOoIW{WHmNDN_-BxHp^5)!h^J6$zZQ`Iw5e*eAikGJYB=bn4+^E~(5 zd*{?iH_dN#zg1IH({%skxUZU;`YkoJO^?3W1k|igzIy}wwp{RZJFces=l2v>SEQz< z&2m5flV4f|j|RK%zj%$gl8BAQM1KW|bK8@vx&GImuN5Bri%TJ8%EMo~=uX5}N%MAA z(2u42J$6@rXUoz(xVzK?ZM79|jDKSlap;@cv(_H-`9W6dyZ%=Ayt;Sq@l$>~Fy(xz zgb((zi_-VQT%)%lNnw%-rbCW~a{bB(uG_nmLZxoIy8Uowrn(yZNB3hp+&5kSW#^9L z53c_3;H$3+jefXor2do9)^Gmy=ccJroGe1r-Dp-$X^5w)I_SkrrwMdG$&19zV)3S{ zw0V43aZ3+&ftXi}7Cva^h(XKJIJ0b%1*-NXEDx$E3Zt zVcaeQlfHlPn|PM0Tz#rp-q1{jDroG1nNSM$zR?u9x2H{*w_#rgZ{p)U_3G}mY`p(V zC-c|m8$|LJa65d7pg0%lUC3iw*bT-Lh@4Keg04@Q^fynHL=WRW_PoL~sGyWHjl{$7 z@l$4s^vKiUE0S>z)7&C{={cW#DuepaMA^B~4o-3Cto3a^)35Kd3Sw%Nr3J^4-glwc z0fMF8g)lqY?tq-_W>1`>XSva$WU9v9Fh@FU$$&RF=@%30u`9nGHz&|Nq4Y;uBn2D4 z!beCwixb=?x7#oCXpax#`5R&SYo(4s?NwM2rCCFBFKv~sp%^#L%P}}>pDvyZbLv*K zGaDtBu$;CL&PeQ8hsP^T^>JwL z-Pjc#<7``xGR?Jen?M}6aLkP?W@Yh^c1{Ny#2PvvHd^2Q{BOL3(o2swE;AP+Ck4X! z5MWugLFOLugq@VfVa{~LbkUXxd9+8pUxi{6W4zCdR$OJ8yRs+NFs*$_M^9CH)r?$8?qjeu$~+R4U2`vAQI#tzD3#(IQ<+!O;S`iAisY2%JPf4= z(Z+mmBAt*_xhFY4Q4)K3VGDQmMqdn6nNA*z?{z%1&&CfC6mm4~Qe3zKDX~3VvPE-$ z+|*i0es4QEC;+1G@XSw}I4c|DMr(#4Da%6`{)SE|p|dq{@z%iWmP0m&OLW;D0Z;tl zOG^sr;*Yk_))uK{kp=**4-zOfArg)4VbzNF!6&SuW+8U|X5WFK^^d#P%>(RKvuTI< z?u4rr;t6ta;U{>S1^6GqNKo&-sSi}ZGMYCR6FDXMR8Romdp=bCD0Z5~*;=|?| zR*rJ^HZ7$Y3mx3Ti~W2ynK zv8KR|AP7W&72vZSm>ndijT~orCD{9$wU+lranvpzB9k8-9gSYdw-<|pt~y2@Qz1}6 z=1NX;eD)d(LxS~IS~3G$&;5iBRw^X~I)#Es;Ze@_-4baHBb^Cobo$4hgl#$&!T2mG zV0muu>Dq~jiQdxD?j&0QQ9@)l+`e<{=Evio@&S)qNQ{?TGE)_1e;AQO1 zAcxCi?j|BBQk``p#<||FLACUDm^jVRBhi*uFH&V!8blm2==%fb=3d|Y5F=`6MCm$a ztmRiXH#fWb$N_^((^=fM{+QU&WB-#?v7hHIG zq8eoOMV0D6#5u5c+6J#11a^|Y)r;p&JIr3)3ahVcq`LR-IMwRr>Q zHVEthCTVG_NyTy>SlJrsotU^vOQkzTj#OYU7=$CF>(X?>0MO}{mH}pgaq>jw_T2}c zndSy|M0k}QitbnJIdPA*AiIX2DmH>KBjXAjXy|n*3K=@OR^4weYjYzaEee5{_?i`G zh?{~sV?Mnr1i&SqsB`+z!7Ow$Tw<}JqM}T5t9>F{*+-_i(w7xtS zJK40`78*=KbaizV?+XwQZ4#G+NKbJG2!?Xv_?9@@8AlNuKT2?9^Z9rV3R`>f358l+ zWf~L|bka%s$$;>5VstcNDQpiB!DS!7mS4lZGmet~%x`rSS=i#dM{(J02&R z)YP-tAKIHH{PcU|ljJjTadC9jUtd~KiyNQ$)~}D;bU|d-%UME{ug?&+37!GSy9>y1 zO*m-jU2emR+aNhgKJK=T=oM39H4M|v`Di1hLy`Fo!gqIenLuZHrSDxpPi*67rrN?Y zK{L{*mb(_1D9&VaX-LZSO`XuQ+Qhwe6~fsYAdj8g5UdjS>`Kj%x%NCA#MpX`w-%dz zm={d4Er8;s43C=jY=sPzHM>~=TQk6|jd=nD17JdjLJls6@?<8^%`v%k4E>1$&vZge zOiYSz#ghU)Yq<|3Ah@c-#z@Ym+BNR!9%i@pX;C|Ueh7vuk8M2$zUj18ZCzFLU(>aJ zld$^|h0#^A4IXblseUSLr`ir;p5AAreE+f`#3M^zV1a-oTH@C)kT|~ehb~RER_EI_ zbakZ&P~T2j&p%kh319*lrv)gMxmCdyrGtyr1x_+PR$%CyEuRV1ZKWE|^cVm{;{8zo zq^2*w(uj?T8F5z0aX8a+-nX$H6dxE&@#*)X$e~9GD@2{tq@+WK4y|#+a2cZB^i`Wn zQwJ`*xm|y{P76SFq)IMbEiW&3%hyL=o_l>bb~1|_4z}mL7|$S05<0HZs&pgX-rL=8 zkoqw{(*g+mXtkRJYH_ypDGCMUPPIi=B)olJ>5`+V*9B}4qH=O_GJ3og#&QAMDb~hK zetmRGn+S+^%J}|sslWU>_J2A02UGbU(TU8F$JUXuwWaX>{18l1v_L%|IDz;fAdI$} zvG6ueQ&W?^{?<0b1_FWT>FFV1;%US%FhEQ9(DPsmL4M#%{{6ItE?_1I6kTJQdj%~Y z^RzU`UY{eV6oURdJ+if3rkFdk2jsB)a_g=io6fdXrIPCF5E(;O{cF8W3-_!ULytRv zGhnVS2QYVx;Q6bsr{~~2@or{lK;s806wB*f9f^fP5f15Be6(Z9C>$TdL8Q&!N#;!A zRsdxJK>6IKI)iDLwfqX#k~t$;VzVh;9apnUA3ZZD_Ndur(KAblZNaIO8-N&ooSv4h z6u{+AZ)jlvp~?Y)XC@|+UVW|8%W)Tf+W*vYtjJH>6#}8Y&C>%NnY~(Nib!WX)&Z0Z zOIJWiITvU&T4O+q6TfF6CHt1+(QT}|Z;U!SI~|ql3$8wXX2pP8w99>()ULR4Cs>A$ zc3%z%01;ua1acxz*T3Emg=Um_mD}JrTP6RTZYRME9Wh)6(DY=*k%X~l?qRaA(k&pv z-l)+ktMIqluA_i^)VOX(`Enm{giW|P2@7|5J0$cAb|@f!IIIj&ZsG&QS-Db>V~}#z zYk1=qHlpHdZW+APeUsQ<$<+AVOVJ+;nUS0}4x_Hi_-8ea&852^)3$~Fe=b)4V%dMV zbA4(0%**MQKz#|+=O_LDBboow^dBF8zVPb{zdoN|pH%AC+YWT!iV4dBUP0B|T~8iI J{e15FKLB@PJcR%N literal 0 HcmV?d00001 diff --git a/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-md-ltr-Mobile-Chrome-linux.png b/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-md-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..7613855bd6de08d7d922b803b4b7e8cfc0938c72 GIT binary patch literal 5474 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 CQ~3J; literal 0 HcmV?d00001 diff --git a/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-md-ltr-Mobile-Safari-linux.png b/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-diff-md-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..c190809cd815f88fc045dca13e2a5cc686f8911a GIT binary patch literal 5090 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 literal 0 HcmV?d00001 diff --git a/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-ios-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..084a1cd1dc4ef79ed45e451fb39e29a4bb9b0d8f GIT binary patch literal 6759 zcmeI1Xm_&pylQ0O#5I}}R2oRZv0Kt%f%x8P<=i7Te-Vf%(UOU;pz1LdrdY=FLuAO@q zTpTsF>26a~Q`3N)`_)ZNZPPt9wau(=HUqzi2M@0S%_g*)qk|f`ckiN_n(ltcufKRi z=dO%nvpi<=K7Mi^79?!V`SIvq8c;0cc*|dz!{5&~kAFjO{orf7iLi%-`vDUZWxSnl z_*;Ncmc{PWFmdPHF{AzWGJg&@rup=bGfyAABHa7+-tI@IfB635=@3%Cps4Nzc@(@2 zMEWVp^R{v;xB%?znHQ_Y1550ACnI|oJrD@Q=I@-PqD<Ts(~7twy3GpVaZ5z(7}e)=fGdmToMZO{Z_vHydj}RV!jp^3kIxzH|7vA}{K3z^M}x?X9+)dsfgZ5y|(Rkup32}zhO`h zRt^O|wUto*Uuf>?Li z+WtkX3bB$h&&rQ;h?PDS!Bvy}4hwg&mKaJ`yl~nIc0{-GdXy03brmI_cMcmw6?DTC zG7%>E<;G&)9*wn(`03k^u^4wM@|O~Xs`L5jPY@a zA%w8*0s(KZ$EX+t^JedST`C#|feXlI60s?&a@lh6eX7qo4A}{$9^{M>z(V~}jy;QF z3HuzZQ!CH!ld#g*OF}p7z(o3kz0&)_u6Ko{H_b*G=|`9D43Y4DmN!F}^5Ob&aCgO- zV0VMMC;ax5p$EGO4MX{r*S2wdvK!am-)`*CB!@Yx@9nME8{qgo9A}5l>&vH+lrv=M=+#S}Z|a5GtRI(8UU>29oXe~82O-B^7*VfBF){;(Z;m~ttM1)a z$y9*_>{R?h1yx9eK(Fy7TEo8Rw)YL^x-9hfRx4$KmktC$Zn;@kq_H=?WLY-Uwa_grRvZGeKD8E;St<`83 z;2}L<@se_)`pt$Y2V@Djm>GX9^wSETS}Vasg^akLBRmg_UNTVD11lVn%PR%h+?4fQULM)YJ&mYT;u4`iNAS7cXN15^RxL&9zg zfH_-f!b&&`(WSGe35K0(`x8foMqNK(pY$I+;)ko@F9(@M%%`T_Eq0RP)?QbB`}aGE z(Z7B|ZvJWDziOUtg4qd&eC*V3d7szbrih(5(Nz91OY`q@#9My@5Bp!6tpdCb1G|3S z8?jHOXy%~$?C3THhMig8FJf$VWQBVTtDC*pXX&84MG$i1>lFG4Twai@w>7U;K1sju z$K#&Hn;)SS>RNj~@aV~!4S8vtVx*}=JRumcWY?t{LSjX(&KC+$Itme@yC9MTcVO3aV1vBXq~X|$iHQO$oR(*U%t{uWW{3` zCm0^uMHrfF8FDZ4AnYQTV)+KjM8!A-y}-hNFsr`hSI!!xF7lFN|ELL_6tdv>U6^kK z@RP{8S)~ZCXl*`&a>Lm@7JO*G4fkWZwu4#hmW1skE_tyWoLGnkHzG$X7sYgy!gXwa zKmK5KkXR{aoM)%b%xb&CpKI!iaf|R#AI&uUQe#;ecLK{p-ndb>-V5rU_;wBD(8>Bv zz5uU3Rnf+5_$7O*SCPHAc~nnXs_2(F3}hUVuTN*IP9ZPFpm87nR1dEm``l5fdr1g~ z)>v3rh!}ixt^2nJyDh?|-X`vgz216PV?Gz%+mmfMxEKMiqB&U;{i<$`)J1aJAMCM2 z&-FY$;Fw|K^91Zl`X8G^qM}$Q$M)4*Z<0Sl(=s82kF+^`JXtieA6aITc^d~CIU$*cp#h(A} zz+rE)T+)YE-ZqdwN%6tPt)dIMXTyos$T}WP#-zaUod+{}@<6Nu!;=i}aH9VWUgUVw z zT=P_XX#D`n)MVGT^BG6}czx*?KR-W$p|-a6`g|X}K5B(Y^64g8UZ^6l(_-6HKo%Gi zR!3GCvv$F?NKn#-1J0*7RPt1jXyCspoWzWUIR*qwSJM?MsQ7gvFb~_wJ3IZU5xU^` zI9@d(FOpf&XV2~+odrcLFDxu%f$_>0nT;w14@Q`wa=uEY68aM80oP-@^W%8yPyqUp z#reC%?wz+`Q3`(hP7!sUgPy+Z<=nRa0QYcL)-0d|CfN_WT05^?O9UT@KX&Eq-v`fU zjKy+E>FMchu+h=cSgoMo;KOEk=^N_xcaQc%2uFNtLc7uqHG;vjY3^NFmi-2R$gjB1 zX4v^PvY_-hBP=i-Gik@+)nU`2y8EWM5dYD-hIxfB-al{q4P-Nd*xR z5w_wnben4vv2-S&j&56G0wEY464=iQl7u6B;1hK6Nt@|8McxSOq>kq~f?*7=aPr{7 z>MBjPT907lq%TFD{xCEY@&2rikk)@FwKGoe%)qZYWV{$kw3l?kLdI&sn*aJ5H#Ryg z`HGi)U{QGrgJ{ER(}C}`zWF=B&_MoCy(3v4 z6vLlkGMRuS&HU;jTJC&n2e;=l_j$u{kyxy(1guzu#ZB!5YL?i=qV7y{mQnP2I-0^W z6=UK=t5we*8A1wS#?|oT530KGHTfRuEL8CBzV}g_xSqq9Uk9Y9YjwkeQ@xK_g=8;r zx$0W`;*JDvZzv33Eg^!RiCQpTMx{2iQP~aOG(P3`~#>Jq+sEF z%U7tv@KFz|fBhlNF4Slpu(RpXSB97P8(1fwQ*Go(?+1wfP8)OqA$zhcW|3cSKIPPx zAzL5J@sF`Q53JBthv{3hHbW_=np=stXiGfH7_bV4RBcoouuB!=8>&U^DVls||0jlu z8}9GFS7tP;tDeRRLc0$>x$0O5RddWctMQLzxNB!$hL2(+$3AZR6Zlxg=3i(2i=^d5 zD_Er-%kD`sr+om_{{H>@;o)>cNMvLr5{dNl8wZSk_Eg&C}C30)vM!WSM%e=fi2w{ir@fS22jZ6;tk8$>%2z^4O zMsjGlm6a9XD)1c;+VJqOBbMJ3R@P%pt*%CWc)g#~sFZ*RYQ_ik%EQYKnqFc^|J z+RK+quPS*0Qs*v#S&YG1=*6AWDMLT61y4Ke$6FU#$)L!i*0Evt8pmEcu^oIML zffa2Bdp?v0$TswRp-={JmgL$USaFSEd2;%JnY=oa3R{)ENQK$g78Ml%vneXNHuS=^NcpVM)7u+XV2_(m1D_RblZubjo(@r&lIuWi;wj^|1-xXS!HdZ`b z=1sXseMusbhW-Q&WnQFU|(*{z@C+VtLyZ{cT_c{ty} zB=S<&xv=OxA|8hx{b_1yAF!m>v4RC5mj%l`QC<`I{^?me4#1la&mpPSsEM)l&dQ*{ z2_YGy4e!gcm%H37CMpPh^PHK2HDXRqe)QD6DXv3dsBEPgFP}Cr zu(8kaG7!(@8hAl?^K_L9!Gf=->fc=4jkiOD;L5bKb!jpd5I zc&-n}M484MA8!P*oMoTw`a5j2rQ@a|lUk@yDEzDoU>$XJb=^um3>>w$CHU1xX(wjd zcRt_!46a!6Zfot-2SvqA>v0yAmU1i+E(F7e4<7>kCh3^luT&25C2}45Mw>z=rcY{e zdR$MJI?+V@w>x34Uc7h*DAeY$;4B)AHcBmh^=cXSLx~|^<5Xi z$x}Q9P-{^z-l3{U42HhevK>gP;gIU(#_VUeXouJRIf(q2V!%S?VrdnCmC?%5iV8G< zA)qrcKJbZoSKMzvHHecgmT=bg9AZ}?u}aB&Qs24k6Jbw{dp6-B1O=wvKkovN2uKeO zq@3hr&AyB+UHudUe=fXsZf*{!)F!{->;aMrpqg8o94DJ+n%Iu?QICi_^lL}sHa>%U z$NzvE&iLn@gAxGo00wJ$8pr|C+q`&o}(jHss5-f83>g3D1}Cd@<+M+G{M4pL{lGs*YLK%ozmgp;{q=9ulfk|K literal 0 HcmV?d00001 diff --git a/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-ios-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..73ad71200738eadf5ccfcf48e2e9a38d799502a8 GIT binary patch literal 12959 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 literal 0 HcmV?d00001 diff --git a/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-md-ltr-Mobile-Chrome-linux.png b/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-md-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..8482f64dbaaf660dd11b1d3706aeac075f3a4162 GIT binary patch literal 5918 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 JejWM4zX9x_7%Kn( literal 0 HcmV?d00001 diff --git a/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-md-ltr-Mobile-Firefox-linux.png b/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-md-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..29c3709ef58e7b6b2b5fb2b4d82aeeaddbc98ade GIT binary patch literal 11793 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 CHCdYg literal 0 HcmV?d00001 diff --git a/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-md-ltr-Mobile-Safari-linux.png b/core/src/components/select-modal/test/basic/select-modal.e2e.ts-snapshots/select-modal-multiple-diff-md-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..b55b7bc77e5fb2f0112fc0fd89f3628f77342abe GIT binary patch literal 5564 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 literal 0 HcmV?d00001 diff --git a/core/src/components/select-modal/test/fixtures.ts b/core/src/components/select-modal/test/fixtures.ts new file mode 100644 index 00000000000..2058848aa84 --- /dev/null +++ b/core/src/components/select-modal/test/fixtures.ts @@ -0,0 +1,73 @@ +import { expect } from '@playwright/test'; +import type { E2EPage, E2ELocator, EventSpy, E2EPageOptions, ScreenshotFn } from '@utils/test/playwright'; + +import type { SelectModalOption } from '../select-modal-interface'; + +export class SelectModalPage { + private page: E2EPage; + private multiple?: boolean; + private options: SelectModalOption[] = []; + + // Locators + modal!: E2ELocator; + selectModal!: E2ELocator; + + // Event spies + ionModalDidDismiss!: EventSpy; + + constructor(page: E2EPage) { + this.page = page; + } + + async setup(config: E2EPageOptions, options: SelectModalOption[], multiple = false) { + const { page } = this; + + await page.setContent( + ` + + + + + `, + config + ); + + const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); + this.ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss'); + + this.modal = page.locator('ion-modal'); + this.selectModal = page.locator('ion-select-modal'); + this.multiple = multiple; + this.options = options; + + await this.modal.evaluate((modal: HTMLIonModalElement) => modal.present()); + + await ionModalDidPresent.next(); + } + + async screenshot(screenshot: ScreenshotFn, name: string) { + await expect(this.selectModal).toHaveScreenshot(screenshot(name)); + } + + async clickOption(value: string) { + const option = this.getOption(value); + await option.click(); + } + + async pressSpaceOnOption(value: string) { + const option = this.getOption(value); + await option.press('Space'); + } + + private getOption(value: string) { + const { multiple, selectModal } = this; + const selector = multiple ? 'ion-checkbox' : 'ion-radio'; + const index = this.options.findIndex((o) => o.value === value); + + return selectModal.locator(selector).nth(index); + } +} diff --git a/core/src/components/select/select-interface.ts b/core/src/components/select/select-interface.ts index 4fa2a18828c..8e65377a825 100644 --- a/core/src/components/select/select-interface.ts +++ b/core/src/components/select/select-interface.ts @@ -1,4 +1,4 @@ -export type SelectInterface = 'action-sheet' | 'popover' | 'alert'; +export type SelectInterface = 'action-sheet' | 'popover' | 'alert' | 'modal'; export type SelectCompareFn = (currentValue: any, compareValue: any) => boolean; diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index bdd8cc0b2e5..3b4ef84f26f 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -4,7 +4,7 @@ import type { NotchController } from '@utils/forms'; import { compareOptions, createNotchController, isOptionSelected } from '@utils/forms'; import { focusVisibleElement, renderHiddenInput, inheritAttributes } from '@utils/helpers'; import type { Attributes } from '@utils/helpers'; -import { actionSheetController, alertController, popoverController } from '@utils/overlays'; +import { actionSheetController, alertController, popoverController, modalController } from '@utils/overlays'; import type { OverlaySelect } from '@utils/overlays-interface'; import { isRTL } from '@utils/rtl'; import { createColorClasses, hostContext } from '@utils/theme'; @@ -19,6 +19,7 @@ import type { CssClassMap, PopoverOptions, StyleEventDetail, + ModalOptions, } from '../../interface'; import type { ActionSheetButton } from '../action-sheet/action-sheet-interface'; import type { AlertInput } from '../alert/alert-interface'; @@ -98,15 +99,15 @@ export class Select implements ComponentInterface { @Prop() fill?: 'outline' | 'solid'; /** - * The interface the select should use: `action-sheet`, `popover` or `alert`. + * The interface the select should use: `action-sheet`, `popover`, `alert`, or `modal`. */ @Prop() interface: SelectInterface = 'alert'; /** * Any additional options that the `alert`, `action-sheet` or `popover` interface * can take. See the [ion-alert docs](./alert), the - * [ion-action-sheet docs](./action-sheet) and the - * [ion-popover docs](./popover) for the + * [ion-action-sheet docs](./action-sheet), the + * [ion-popover docs](./popover), and the [ion-modal docs](./modal) for the * create options for each interface. * * Note: `interfaceOptions` will not override `inputs` or `buttons` with the `alert` interface. @@ -318,9 +319,9 @@ export class Select implements ComponentInterface { await overlay.present(); - // focus selected option for popovers - if (this.interface === 'popover') { - const indexOfSelected = this.childOpts.map((o) => o.value).indexOf(this.value); + // focus selected option for popovers and modals + if (this.interface === 'popover' || this.interface === 'modal') { + const indexOfSelected = this.childOpts.findIndex((o) => o.value === this.value); if (indexOfSelected > -1) { const selectedItem = overlay.querySelector( @@ -328,8 +329,6 @@ export class Select implements ComponentInterface { ); if (selectedItem) { - focusVisibleElement(selectedItem); - /** * Browsers such as Firefox do not * correctly delegate focus when manually @@ -341,10 +340,17 @@ export class Select implements ComponentInterface { * we only need to worry about those two components * when focusing. */ - const interactiveEl = selectedItem.querySelector('ion-radio, ion-checkbox'); + const interactiveEl = selectedItem.querySelector('ion-radio, ion-checkbox') as + | HTMLIonRadioElement + | HTMLIonCheckboxElement + | null; if (interactiveEl) { - interactiveEl.focus(); + // Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling + // and removing `ion-focused` style + interactiveEl.setFocus(); } + + focusVisibleElement(selectedItem); } } else { /** @@ -352,14 +358,18 @@ export class Select implements ComponentInterface { */ const firstEnabledOption = overlay.querySelector( 'ion-radio:not(.radio-disabled), ion-checkbox:not(.checkbox-disabled)' - ); - if (firstEnabledOption) { - focusVisibleElement(firstEnabledOption.closest('ion-item')!); + ) as HTMLIonRadioElement | HTMLIonCheckboxElement | null; + if (firstEnabledOption) { /** * Focus the option for the same reason as we do above. + * + * Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling + * and removing `ion-focused` style */ - firstEnabledOption.focus(); + firstEnabledOption.setFocus(); + + focusVisibleElement(firstEnabledOption.closest('ion-item')!); } } } @@ -389,6 +399,9 @@ export class Select implements ComponentInterface { if (selectInterface === 'popover') { return this.openPopover(ev!); } + if (selectInterface === 'modal') { + return this.openModal(); + } return this.openAlert(); } @@ -406,7 +419,13 @@ export class Select implements ComponentInterface { case 'popover': const popover = overlay.querySelector('ion-select-popover'); if (popover) { - popover.options = this.createPopoverOptions(childOpts, value); + popover.options = this.createOverlaySelectOptions(childOpts, value); + } + break; + case 'modal': + const modal = overlay.querySelector('ion-select-modal'); + if (modal) { + modal.options = this.createOverlaySelectOptions(childOpts, value); } break; case 'alert': @@ -475,7 +494,7 @@ export class Select implements ComponentInterface { return alertInputs; } - private createPopoverOptions(data: HTMLIonSelectOptionElement[], selectValue: any): SelectPopoverOption[] { + private createOverlaySelectOptions(data: HTMLIonSelectOptionElement[], selectValue: any): SelectPopoverOption[] { const popoverOptions = data.map((option) => { const value = getOptionValue(option); @@ -553,7 +572,7 @@ export class Select implements ComponentInterface { message: interfaceOptions.message, multiple, value, - options: this.createPopoverOptions(this.childOpts, value), + options: this.createOverlaySelectOptions(this.childOpts, value), }, }; @@ -647,6 +666,40 @@ export class Select implements ComponentInterface { return alertController.create(alertOpts); } + private openModal() { + const { multiple, value, interfaceOptions } = this; + const mode = getIonMode(this); + + const modalOpts: ModalOptions = { + ...interfaceOptions, + mode, + + cssClass: ['select-modal', interfaceOptions.cssClass], + component: 'ion-select-modal', + componentProps: { + header: interfaceOptions.header, + multiple, + value, + options: this.createOverlaySelectOptions(this.childOpts, value), + }, + }; + + /** + * Workaround for Stencil to autodefine + * ion-select-modal and ion-modal when + * using Custom Elements build. + */ + // eslint-disable-next-line + if (false) { + // eslint-disable-next-line + // @ts-ignore + document.createElement('ion-select-modal'); + document.createElement('ion-modal'); + } + + return modalController.create(modalOpts); + } + /** * Close the select interface. */ diff --git a/core/src/components/select/test/basic/index.html b/core/src/components/select/test/basic/index.html index 421dd4505fe..c958d08f909 100644 --- a/core/src/components/select/test/basic/index.html +++ b/core/src/components/select/test/basic/index.html @@ -51,6 +51,14 @@ Pears + + + + Apples + Oranges + Pears + + @@ -76,6 +84,15 @@ Honey Badger + + + + Bird + Cat + Dog + Honey Badger + + @@ -124,6 +141,16 @@ Onions + + + + Pepperoni + Bacon + Extra Cheese + Mushrooms + Onions + + @@ -152,6 +179,14 @@ message: '$1.50 charge for every topping', }; customActionSheetSelect.interfaceOptions = customActionSheetOptions; + + var customModalSelect = document.getElementById('customModalSelect'); + var customModalSheetOptions = { + header: 'Pizza Toppings', + breakpoints: [0.5], + initialBreakpoint: 0.5, + }; + customModalSelect.interfaceOptions = customModalSheetOptions; diff --git a/core/src/components/select/test/basic/select.e2e.ts b/core/src/components/select/test/basic/select.e2e.ts index d44c8ca7619..35747728495 100644 --- a/core/src/components/select/test/basic/select.e2e.ts +++ b/core/src/components/select/test/basic/select.e2e.ts @@ -58,6 +58,24 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => { await expect(popover).toBeVisible(); }); }); + + test.describe('select: modal', () => { + test('it should open a modal select', async ({ page }) => { + const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); + + await page.click('#customModalSelect'); + + await ionModalDidPresent.next(); + + const modal = page.locator('ion-modal'); + + // select has no value, so first option should be focused by default + const modalOption1 = modal.locator('.select-interface-option:first-of-type ion-radio'); + await expect(modalOption1).toBeFocused(); + + await expect(modal).toBeVisible(); + }); + }); }); }); diff --git a/core/src/utils/overlays-interface.ts b/core/src/utils/overlays-interface.ts index 4a37fca71ab..63f70baac8b 100644 --- a/core/src/utils/overlays-interface.ts +++ b/core/src/utils/overlays-interface.ts @@ -46,4 +46,8 @@ export interface HTMLIonOverlayElement extends HTMLStencilElement { present: () => Promise; } -export type OverlaySelect = HTMLIonActionSheetElement | HTMLIonAlertElement | HTMLIonPopoverElement; +export type OverlaySelect = + | HTMLIonActionSheetElement + | HTMLIonAlertElement + | HTMLIonPopoverElement + | HTMLIonModalElement; diff --git a/packages/angular/src/directives/proxies-list.ts b/packages/angular/src/directives/proxies-list.ts index 1874d0bfe2d..93d0cc13ad9 100644 --- a/packages/angular/src/directives/proxies-list.ts +++ b/packages/angular/src/directives/proxies-list.ts @@ -70,6 +70,7 @@ export const DIRECTIVES = [ d.IonSegment, d.IonSegmentButton, d.IonSelect, + d.IonSelectModal, d.IonSelectOption, d.IonSkeletonText, d.IonSpinner, diff --git a/packages/angular/src/directives/proxies.ts b/packages/angular/src/directives/proxies.ts index 89558cb46a1..e384f56c531 100644 --- a/packages/angular/src/directives/proxies.ts +++ b/packages/angular/src/directives/proxies.ts @@ -2057,6 +2057,28 @@ This event will not emit when programmatically setting the `value` property. } +@ProxyCmp({ + inputs: ['header', 'multiple', 'options'] +}) +@Component({ + selector: 'ion-select-modal', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['header', 'multiple', 'options'], +}) +export class IonSelectModal { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface IonSelectModal extends Components.IonSelectModal {} + + @ProxyCmp({ inputs: ['disabled', 'value'] }) diff --git a/packages/angular/standalone/src/directives/proxies.ts b/packages/angular/standalone/src/directives/proxies.ts index b0426e56968..5fac940a661 100644 --- a/packages/angular/standalone/src/directives/proxies.ts +++ b/packages/angular/standalone/src/directives/proxies.ts @@ -65,6 +65,7 @@ import { defineCustomElement as defineIonReorderGroup } from '@ionic/core/compon import { defineCustomElement as defineIonRippleEffect } from '@ionic/core/components/ion-ripple-effect.js'; import { defineCustomElement as defineIonRow } from '@ionic/core/components/ion-row.js'; import { defineCustomElement as defineIonSegmentButton } from '@ionic/core/components/ion-segment-button.js'; +import { defineCustomElement as defineIonSelectModal } from '@ionic/core/components/ion-select-modal.js'; import { defineCustomElement as defineIonSelectOption } from '@ionic/core/components/ion-select-option.js'; import { defineCustomElement as defineIonSkeletonText } from '@ionic/core/components/ion-skeleton-text.js'; import { defineCustomElement as defineIonSpinner } from '@ionic/core/components/ion-spinner.js'; @@ -1841,6 +1842,30 @@ export class IonSegmentButton { export declare interface IonSegmentButton extends Components.IonSegmentButton {} +@ProxyCmp({ + defineCustomElementFn: defineIonSelectModal, + inputs: ['header', 'multiple', 'options'] +}) +@Component({ + selector: 'ion-select-modal', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['header', 'multiple', 'options'], + standalone: true +}) +export class IonSelectModal { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface IonSelectModal extends Components.IonSelectModal {} + + @ProxyCmp({ defineCustomElementFn: defineIonSelectOption, inputs: ['disabled', 'value'] diff --git a/packages/react/src/components/proxies.ts b/packages/react/src/components/proxies.ts index 05800f38773..14f81d30ebd 100644 --- a/packages/react/src/components/proxies.ts +++ b/packages/react/src/components/proxies.ts @@ -62,6 +62,7 @@ import { defineCustomElement as defineIonSearchbar } from '@ionic/core/component import { defineCustomElement as defineIonSegment } from '@ionic/core/components/ion-segment.js'; import { defineCustomElement as defineIonSegmentButton } from '@ionic/core/components/ion-segment-button.js'; import { defineCustomElement as defineIonSelect } from '@ionic/core/components/ion-select.js'; +import { defineCustomElement as defineIonSelectModal } from '@ionic/core/components/ion-select-modal.js'; import { defineCustomElement as defineIonSelectOption } from '@ionic/core/components/ion-select-option.js'; import { defineCustomElement as defineIonSkeletonText } from '@ionic/core/components/ion-skeleton-text.js'; import { defineCustomElement as defineIonSpinner } from '@ionic/core/components/ion-spinner.js'; @@ -131,6 +132,7 @@ export const IonSearchbar = /*@__PURE__*/createReactComponent('ion-segment', undefined, undefined, defineIonSegment); export const IonSegmentButton = /*@__PURE__*/createReactComponent('ion-segment-button', undefined, undefined, defineIonSegmentButton); export const IonSelect = /*@__PURE__*/createReactComponent('ion-select', undefined, undefined, defineIonSelect); +export const IonSelectModal = /*@__PURE__*/createReactComponent('ion-select-modal', undefined, undefined, defineIonSelectModal); export const IonSelectOption = /*@__PURE__*/createReactComponent('ion-select-option', undefined, undefined, defineIonSelectOption); export const IonSkeletonText = /*@__PURE__*/createReactComponent('ion-skeleton-text', undefined, undefined, defineIonSkeletonText); export const IonSpinner = /*@__PURE__*/createReactComponent('ion-spinner', undefined, undefined, defineIonSpinner); diff --git a/packages/vue/src/proxies.ts b/packages/vue/src/proxies.ts index 347673a7461..0d93a32c46d 100644 --- a/packages/vue/src/proxies.ts +++ b/packages/vue/src/proxies.ts @@ -68,6 +68,7 @@ import { defineCustomElement as defineIonSearchbar } from '@ionic/core/component import { defineCustomElement as defineIonSegment } from '@ionic/core/components/ion-segment.js'; import { defineCustomElement as defineIonSegmentButton } from '@ionic/core/components/ion-segment-button.js'; import { defineCustomElement as defineIonSelect } from '@ionic/core/components/ion-select.js'; +import { defineCustomElement as defineIonSelectModal } from '@ionic/core/components/ion-select-modal.js'; import { defineCustomElement as defineIonSelectOption } from '@ionic/core/components/ion-select-option.js'; import { defineCustomElement as defineIonSkeletonText } from '@ionic/core/components/ion-skeleton-text.js'; import { defineCustomElement as defineIonSpinner } from '@ionic/core/components/ion-spinner.js'; @@ -782,6 +783,13 @@ export const IonSelect = /*@__PURE__*/ defineContainer('ion-select-modal', defineIonSelectModal, [ + 'header', + 'multiple', + 'options' +]); + + export const IonSelectOption = /*@__PURE__*/ defineContainer('ion-select-option', defineIonSelectOption, [ 'disabled', 'value'