From 2425bee592fe8ebc96044d1189218cb5c36f9b38 Mon Sep 17 00:00:00 2001 From: Shawn Taylor Date: Wed, 1 Nov 2023 14:15:52 -0400 Subject: [PATCH 1/9] feat(radio-group): add compareWith property Co-authored-by: Sean Perkins --- core/src/components.d.ts | 16 +++- .../radio-group/radio-group-interface.ts | 2 + .../components/radio-group/radio-group.tsx | 10 ++- .../radio-group/test/compare-with/index.html | 76 +++++++++++++++++++ core/src/components/radio/radio.tsx | 6 +- core/src/components/select/select.tsx | 36 ++------- core/src/utils/forms/compare-with-utils.ts | 37 +++++++++ core/src/utils/forms/index.ts | 1 + 8 files changed, 146 insertions(+), 38 deletions(-) create mode 100644 core/src/components/radio-group/test/compare-with/index.html create mode 100644 core/src/utils/forms/compare-with-utils.ts diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 8dcb3cb3ba3..447c95efad1 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -27,7 +27,7 @@ import { PickerButton, PickerColumn } from "./components/picker/picker-interface import { PickerColumnItem } from "./components/picker-column-internal/picker-column-internal-interfaces"; import { PickerInternalChangeEventDetail } from "./components/picker-internal/picker-internal-interfaces"; import { PopoverSize, PositionAlign, PositionReference, PositionSide, TriggerAction } from "./components/popover/popover-interface"; -import { RadioGroupChangeEventDetail } from "./components/radio-group/radio-group-interface"; +import { RadioGroupChangeEventDetail, RadioGroupCompareFn } from "./components/radio-group/radio-group-interface"; import { PinFormatter, RangeChangeEventDetail, RangeKnobMoveEndEventDetail, RangeKnobMoveStartEventDetail, RangeValue } from "./components/range/range-interface"; import { RefresherEventDetail } from "./components/refresher/refresher-interface"; import { ItemReorderEventDetail } from "./components/reorder-group/reorder-group-interface"; @@ -63,7 +63,7 @@ export { PickerButton, PickerColumn } from "./components/picker/picker-interface export { PickerColumnItem } from "./components/picker-column-internal/picker-column-internal-interfaces"; export { PickerInternalChangeEventDetail } from "./components/picker-internal/picker-internal-interfaces"; export { PopoverSize, PositionAlign, PositionReference, PositionSide, TriggerAction } from "./components/popover/popover-interface"; -export { RadioGroupChangeEventDetail } from "./components/radio-group/radio-group-interface"; +export { RadioGroupChangeEventDetail, RadioGroupCompareFn } from "./components/radio-group/radio-group-interface"; export { PinFormatter, RangeChangeEventDetail, RangeKnobMoveEndEventDetail, RangeKnobMoveStartEventDetail, RangeValue } from "./components/range/range-interface"; export { RefresherEventDetail } from "./components/refresher/refresher-interface"; export { ItemReorderEventDetail } from "./components/reorder-group/reorder-group-interface"; @@ -2265,6 +2265,10 @@ export namespace Components { * If `true`, the radios can be deselected. */ "allowEmptySelection": boolean; + /** + * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-radio-group. When not specified, the default behavior will use object equality (===) for comparison. + */ + "compareWith"?: string | RadioGroupCompareFn | null; /** * The name of the control, which is submitted with the form data. */ @@ -2684,7 +2688,7 @@ export namespace Components { */ "color"?: Color; /** - * A property name or function used to compare object values + * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-select. When not specified, the default behavior will use object equality (===) for comparison. */ "compareWith"?: string | SelectCompareFn | null; /** @@ -6306,6 +6310,10 @@ declare namespace LocalJSX { * If `true`, the radios can be deselected. */ "allowEmptySelection"?: boolean; + /** + * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-radio-group. When not specified, the default behavior will use object equality (===) for comparison. + */ + "compareWith"?: string | RadioGroupCompareFn | null; /** * The name of the control, which is submitted with the form data. */ @@ -6788,7 +6796,7 @@ declare namespace LocalJSX { */ "color"?: Color; /** - * A property name or function used to compare object values + * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-select. When not specified, the default behavior will use object equality (===) for comparison. */ "compareWith"?: string | SelectCompareFn | null; /** diff --git a/core/src/components/radio-group/radio-group-interface.ts b/core/src/components/radio-group/radio-group-interface.ts index 3aea4602885..993c0840625 100644 --- a/core/src/components/radio-group/radio-group-interface.ts +++ b/core/src/components/radio-group/radio-group-interface.ts @@ -7,3 +7,5 @@ export interface RadioGroupCustomEvent extends CustomEvent { detail: RadioGroupChangeEventDetail; target: HTMLIonRadioGroupElement; } + +export type RadioGroupCompareFn = (currentValue: any, compareValue: any) => boolean; diff --git a/core/src/components/radio-group/radio-group.tsx b/core/src/components/radio-group/radio-group.tsx index 9a61befae3b..31cfda38b32 100644 --- a/core/src/components/radio-group/radio-group.tsx +++ b/core/src/components/radio-group/radio-group.tsx @@ -4,7 +4,7 @@ import { renderHiddenInput } from '@utils/helpers'; import { getIonMode } from '../../global/ionic-global'; -import type { RadioGroupChangeEventDetail } from './radio-group-interface'; +import type { RadioGroupChangeEventDetail, RadioGroupCompareFn } from './radio-group-interface'; @Component({ tag: 'ion-radio-group', @@ -21,6 +21,14 @@ export class RadioGroup implements ComponentInterface { */ @Prop() allowEmptySelection = false; + /** + * This property allows developers to specify a custom function or property + * name for comparing objects when determining the selected option in the + * ion-radio-group. When not specified, the default behavior will use object + * equality (===) for comparison. + */ + @Prop() compareWith?: string | RadioGroupCompareFn | null; + /** * The name of the control, which is submitted with the form data. */ diff --git a/core/src/components/radio-group/test/compare-with/index.html b/core/src/components/radio-group/test/compare-with/index.html new file mode 100644 index 00000000000..353e9307ba7 --- /dev/null +++ b/core/src/components/radio-group/test/compare-with/index.html @@ -0,0 +1,76 @@ + + + + + Radio Group - compareWith + + + + + + + + + + + + + Radio Group - compareWith + + + + + + Compare with String + + + + + Compare with Function + + + + + + + + diff --git a/core/src/components/radio/radio.tsx b/core/src/components/radio/radio.tsx index 864a0dd4860..0842a4f55c1 100644 --- a/core/src/components/radio/radio.tsx +++ b/core/src/components/radio/radio.tsx @@ -1,7 +1,7 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core'; import { Component, Element, Event, Host, Method, Prop, State, Watch, h } from '@stencil/core'; import type { LegacyFormController } from '@utils/forms'; -import { createLegacyFormController } from '@utils/forms'; +import { createLegacyFormController, isOptionSelected } from '@utils/forms'; import { addEventListener, getAriaLabel, removeEventListener } from '@utils/helpers'; import { printIonWarning } from '@utils/logging'; import { createColorClasses, hostContext } from '@utils/theme'; @@ -197,7 +197,9 @@ export class Radio implements ComponentInterface { private updateState = () => { if (this.radioGroup) { - this.checked = this.radioGroup.value === this.value; + const { compareWith, value: radioGroupValue } = this.radioGroup; + + this.checked = isOptionSelected(radioGroupValue, this.value, compareWith); } }; diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index df8a00ae182..ade6f79de62 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -1,7 +1,7 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core'; import { Component, Element, Event, Host, Method, Prop, State, Watch, h, forceUpdate } from '@stencil/core'; import type { LegacyFormController, NotchController } from '@utils/forms'; -import { createLegacyFormController, createNotchController } from '@utils/forms'; +import { compareOptions, createLegacyFormController, createNotchController, isOptionSelected } from '@utils/forms'; import { findItemLabel, focusElement, getAriaLabel, renderHiddenInput, inheritAttributes } from '@utils/helpers'; import type { Attributes } from '@utils/helpers'; import { printIonWarning } from '@utils/logging'; @@ -82,7 +82,10 @@ export class Select implements ComponentInterface { @Prop({ reflect: true }) color?: Color; /** - * A property name or function used to compare object values + * This property allows developers to specify a custom function or property + * name for comparing objects when determining the selected option in the + * ion-select. When not specified, the default behavior will use object + * equality (===) for comparison. */ @Prop() compareWith?: string | SelectCompareFn | null; @@ -1076,21 +1079,6 @@ Developers can use the "legacy" property to continue using the legacy form marku } } -const isOptionSelected = ( - currentValue: any[] | any, - compareValue: any, - compareWith?: string | SelectCompareFn | null -) => { - if (currentValue === undefined) { - return false; - } - if (Array.isArray(currentValue)) { - return currentValue.some((val) => compareOptions(val, compareValue, compareWith)); - } else { - return compareOptions(currentValue, compareValue, compareWith); - } -}; - const getOptionValue = (el: HTMLIonSelectOptionElement) => { const value = el.value; return value === undefined ? el.textContent || '' : value; @@ -1106,20 +1094,6 @@ const parseValue = (value: any) => { return value.toString(); }; -const compareOptions = ( - currentValue: any, - compareValue: any, - compareWith?: string | SelectCompareFn | null -): boolean => { - if (typeof compareWith === 'function') { - return compareWith(currentValue, compareValue); - } else if (typeof compareWith === 'string') { - return currentValue[compareWith] === compareValue[compareWith]; - } else { - return Array.isArray(compareValue) ? compareValue.includes(currentValue) : currentValue === compareValue; - } -}; - const generateText = ( opts: HTMLIonSelectOptionElement[], value: any | any[], diff --git a/core/src/utils/forms/compare-with-utils.ts b/core/src/utils/forms/compare-with-utils.ts new file mode 100644 index 00000000000..36cff8eac8f --- /dev/null +++ b/core/src/utils/forms/compare-with-utils.ts @@ -0,0 +1,37 @@ +type CompareFn = (currentValue: any, compareValue: any) => boolean; + +export const compareOptions = ( + currentValue: any, + compareValue: any, + compareWith?: string | CompareFn | null +): boolean => { + if (typeof compareWith === 'function') { + return compareWith(currentValue, compareValue); + } else if (typeof compareWith === 'string') { + return currentValue[compareWith] === compareValue[compareWith]; + } else { + return Array.isArray(compareValue) ? compareValue.includes(currentValue) : currentValue === compareValue; + } +}; + +/** + * Compares a value against the current value to determine if it is selected. + * + * @param currentValue The current value of the control. + * @param compareValue The value to compare against. + * @param compareWith The function to use to compare values. + */ +export const isOptionSelected = ( + currentValue: any[] | any, + compareValue: any, + compareWith?: string | CompareFn | null +) => { + if (currentValue === undefined) { + return false; + } + if (Array.isArray(currentValue)) { + return currentValue.some((val) => compareOptions(val, compareValue, compareWith)); + } else { + return compareOptions(currentValue, compareValue, compareWith); + } +}; diff --git a/core/src/utils/forms/index.ts b/core/src/utils/forms/index.ts index f219f3978a9..5b870bd513a 100644 --- a/core/src/utils/forms/index.ts +++ b/core/src/utils/forms/index.ts @@ -1,2 +1,3 @@ export * from './form-controller'; export * from './notch-controller'; +export * from './compare-with-utils'; From 5187f7cf52b2a4699c5aed943c6e9bcc6409b997 Mon Sep 17 00:00:00 2001 From: Shawn Taylor Date: Wed, 1 Nov 2023 15:03:38 -0400 Subject: [PATCH 2/9] Fix value in tests --- core/src/components/radio-group/test/compare-with/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/components/radio-group/test/compare-with/index.html b/core/src/components/radio-group/test/compare-with/index.html index 353e9307ba7..57fe6abb3f6 100644 --- a/core/src/components/radio-group/test/compare-with/index.html +++ b/core/src/components/radio-group/test/compare-with/index.html @@ -52,11 +52,11 @@ ]; const radioGroupWithString = document.querySelector('#compareWithString'); - radioGroupWithString.value = [options[1]]; + radioGroupWithString.value = options[1]; const radioGroupWithFn = document.querySelector('#compareWithFn'); radioGroupWithFn.compareWith = (a, b) => a.value === b.value; - radioGroupWithFn.value = [options[1]]; + radioGroupWithFn.value = options[1]; document.querySelectorAll('ion-radio-group').forEach((radioGroup) => { options.forEach((option) => { From 45e4e142d2730975403a3e5e9fd06c6b1ca22b3e Mon Sep 17 00:00:00 2001 From: Shawn Taylor Date: Wed, 1 Nov 2023 15:05:34 -0400 Subject: [PATCH 3/9] Add tests --- .../test/compare-with/radio-group.e2e.ts | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 core/src/components/radio-group/test/compare-with/radio-group.e2e.ts diff --git a/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts b/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts new file mode 100644 index 00000000000..a14a72e4c63 --- /dev/null +++ b/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts @@ -0,0 +1,46 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +/** + * This behavior does not vary across modes/directions. + */ +configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('radio-group: compare-with'), () => { + test('should correctly set value when using compareWith string', async ({ page }) => { + await page.goto('/src/components/radio-group/test/compare-with', config); + + const radioGroupWithString = page.locator('#compareWithString'); + + await expect(radioGroupWithString).toHaveJSProperty('value', { + label: 'Blue', + value: 'blue', + }); + }); + + test('should correctly set value when using compareWith function', async ({ page }) => { + await page.goto('/src/components/radio-group/test/compare-with', config); + + const radioGroupWithFn = page.locator('#compareWithFn'); + + await expect(radioGroupWithFn).toHaveJSProperty('value', { + label: 'Blue', + value: 'blue', + }); + }); + + test('should correctly set value to an object when clicked', async ({ page }) => { + await page.goto('/src/components/radio-group/test/compare-with', config); + + const radioGroupWithFn = page.locator('#compareWithFn'); + + const firstRadio = radioGroupWithFn.locator('ion-radio').first(); + await firstRadio.click(); + await page.waitForChanges(); + + await expect(radioGroupWithFn).toHaveJSProperty('value', { + label: 'Red', + value: 'red', + }); + }); + }); +}); From 52b99e664a96106e33f34e85a03aad0d8fc104a8 Mon Sep 17 00:00:00 2001 From: Shawn Taylor Date: Wed, 1 Nov 2023 15:32:40 -0400 Subject: [PATCH 4/9] Add test --- .../radio-group/test/compare-with/index.html | 2 +- .../test/compare-with/radio-group.e2e.ts | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/core/src/components/radio-group/test/compare-with/index.html b/core/src/components/radio-group/test/compare-with/index.html index 57fe6abb3f6..a2f7776e7eb 100644 --- a/core/src/components/radio-group/test/compare-with/index.html +++ b/core/src/components/radio-group/test/compare-with/index.html @@ -25,7 +25,7 @@ Compare with String - + diff --git a/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts b/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts index a14a72e4c63..70aa9706caa 100644 --- a/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts +++ b/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts @@ -42,5 +42,50 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => value: 'red', }); }); + + test('should work with different parameter types', async ({ page }) => { + test.info().annotations.push({ + type: 'issue', + description: 'https://github.com/ionic-team/ionic-framework/issues/25759', + }); + + await page.setContent( + ` + + + + `, + config + ); + + const radios = page.locator('ion-radio'); + + await expect(radios.nth(0)).toHaveAttribute('aria-checked', 'false'); + await expect(radios.nth(1)).toHaveAttribute('aria-checked', 'false'); + await expect(radios.nth(2)).toHaveAttribute('aria-checked', 'true'); + }); }); }); From 8d9e845b34f7560f9bb67a84dbd641b5ad2fdb12 Mon Sep 17 00:00:00 2001 From: Shawn Taylor Date: Wed, 1 Nov 2023 16:16:15 -0400 Subject: [PATCH 5/9] Build --- core/api.txt | 1 + core/src/components.d.ts | 635 +++++++++++++++++++++ packages/angular/src/directives/proxies.ts | 4 +- packages/vue/src/proxies.ts | 1 + 4 files changed, 639 insertions(+), 2 deletions(-) diff --git a/core/api.txt b/core/api.txt index d54e7a6f408..a5619099b68 100644 --- a/core/api.txt +++ b/core/api.txt @@ -1033,6 +1033,7 @@ ion-radio,part,mark ion-radio-group,none ion-radio-group,prop,allowEmptySelection,boolean,false,false,false +ion-radio-group,prop,compareWith,((currentValue: any, compareValue: any) => boolean) | null | string | undefined,undefined,false,false ion-radio-group,prop,name,string,this.inputId,false,false ion-radio-group,prop,value,any,undefined,false,false ion-radio-group,event,ionChange,RadioGroupChangeEventDetail,true diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 447c95efad1..2d878823fcd 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -3433,19 +3433,67 @@ declare global { prototype: HTMLIonAccordionElement; new (): HTMLIonAccordionElement; }; + interface HTMLIonAccordionGroupElementEventMap { + "ionChange": AccordionGroupChangeEventDetail; + "ionValueChange": AccordionGroupChangeEventDetail; + } interface HTMLIonAccordionGroupElement extends Components.IonAccordionGroup, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonAccordionGroupElement, ev: IonAccordionGroupCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonAccordionGroupElement, ev: IonAccordionGroupCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonAccordionGroupElement: { prototype: HTMLIonAccordionGroupElement; new (): HTMLIonAccordionGroupElement; }; + interface HTMLIonActionSheetElementEventMap { + "ionActionSheetDidPresent": void; + "ionActionSheetWillPresent": void; + "ionActionSheetWillDismiss": OverlayEventDetail; + "ionActionSheetDidDismiss": OverlayEventDetail; + "didPresent": void; + "willPresent": void; + "willDismiss": OverlayEventDetail; + "didDismiss": OverlayEventDetail; + } interface HTMLIonActionSheetElement extends Components.IonActionSheet, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonActionSheetElement, ev: IonActionSheetCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonActionSheetElement, ev: IonActionSheetCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonActionSheetElement: { prototype: HTMLIonActionSheetElement; new (): HTMLIonActionSheetElement; }; + interface HTMLIonAlertElementEventMap { + "ionAlertDidPresent": void; + "ionAlertWillPresent": void; + "ionAlertWillDismiss": OverlayEventDetail; + "ionAlertDidDismiss": OverlayEventDetail; + "didPresent": void; + "willPresent": void; + "willDismiss": OverlayEventDetail; + "didDismiss": OverlayEventDetail; + } interface HTMLIonAlertElement extends Components.IonAlert, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonAlertElement, ev: IonAlertCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonAlertElement, ev: IonAlertCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonAlertElement: { prototype: HTMLIonAlertElement; @@ -3469,7 +3517,18 @@ declare global { prototype: HTMLIonBackButtonElement; new (): HTMLIonBackButtonElement; }; + interface HTMLIonBackdropElementEventMap { + "ionBackdropTap": void; + } interface HTMLIonBackdropElement extends Components.IonBackdrop, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonBackdropElement, ev: IonBackdropCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonBackdropElement, ev: IonBackdropCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonBackdropElement: { prototype: HTMLIonBackdropElement; @@ -3481,19 +3540,55 @@ declare global { prototype: HTMLIonBadgeElement; new (): HTMLIonBadgeElement; }; + interface HTMLIonBreadcrumbElementEventMap { + "ionFocus": void; + "ionBlur": void; + "collapsedClick": BreadcrumbCollapsedClickEventDetail; + } interface HTMLIonBreadcrumbElement extends Components.IonBreadcrumb, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonBreadcrumbElement, ev: IonBreadcrumbCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonBreadcrumbElement, ev: IonBreadcrumbCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonBreadcrumbElement: { prototype: HTMLIonBreadcrumbElement; new (): HTMLIonBreadcrumbElement; }; + interface HTMLIonBreadcrumbsElementEventMap { + "ionCollapsedClick": BreadcrumbCollapsedClickEventDetail; + } interface HTMLIonBreadcrumbsElement extends Components.IonBreadcrumbs, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonBreadcrumbsElement, ev: IonBreadcrumbsCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonBreadcrumbsElement, ev: IonBreadcrumbsCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonBreadcrumbsElement: { prototype: HTMLIonBreadcrumbsElement; new (): HTMLIonBreadcrumbsElement; }; + interface HTMLIonButtonElementEventMap { + "ionFocus": void; + "ionBlur": void; + } interface HTMLIonButtonElement extends Components.IonButton, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonButtonElement, ev: IonButtonCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonButtonElement, ev: IonButtonCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonButtonElement: { prototype: HTMLIonButtonElement; @@ -3535,7 +3630,21 @@ declare global { prototype: HTMLIonCardTitleElement; new (): HTMLIonCardTitleElement; }; + interface HTMLIonCheckboxElementEventMap { + "ionChange": CheckboxChangeEventDetail; + "ionFocus": void; + "ionBlur": void; + "ionStyle": StyleEventDetail; + } interface HTMLIonCheckboxElement extends Components.IonCheckbox, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonCheckboxElement, ev: IonCheckboxCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonCheckboxElement, ev: IonCheckboxCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonCheckboxElement: { prototype: HTMLIonCheckboxElement; @@ -3553,13 +3662,43 @@ declare global { prototype: HTMLIonColElement; new (): HTMLIonColElement; }; + interface HTMLIonContentElementEventMap { + "ionScrollStart": ScrollBaseDetail; + "ionScroll": ScrollDetail; + "ionScrollEnd": ScrollBaseDetail; + } interface HTMLIonContentElement extends Components.IonContent, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonContentElement, ev: IonContentCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonContentElement, ev: IonContentCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonContentElement: { prototype: HTMLIonContentElement; new (): HTMLIonContentElement; }; + interface HTMLIonDatetimeElementEventMap { + "ionCancel": void; + "ionChange": DatetimeChangeEventDetail; + "ionValueChange": DatetimeChangeEventDetail; + "ionFocus": void; + "ionBlur": void; + "ionStyle": StyleEventDetail; + "ionRender": void; + } interface HTMLIonDatetimeElement extends Components.IonDatetime, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonDatetimeElement, ev: IonDatetimeCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonDatetimeElement, ev: IonDatetimeCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonDatetimeElement: { prototype: HTMLIonDatetimeElement; @@ -3577,7 +3716,19 @@ declare global { prototype: HTMLIonFabElement; new (): HTMLIonFabElement; }; + interface HTMLIonFabButtonElementEventMap { + "ionFocus": void; + "ionBlur": void; + } interface HTMLIonFabButtonElement extends Components.IonFabButton, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonFabButtonElement, ev: IonFabButtonCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonFabButtonElement, ev: IonFabButtonCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonFabButtonElement: { prototype: HTMLIonFabButtonElement; @@ -3607,13 +3758,37 @@ declare global { prototype: HTMLIonHeaderElement; new (): HTMLIonHeaderElement; }; + interface HTMLIonImgElementEventMap { + "ionImgWillLoad": void; + "ionImgDidLoad": void; + "ionError": void; + } interface HTMLIonImgElement extends Components.IonImg, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonImgElement, ev: IonImgCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonImgElement, ev: IonImgCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonImgElement: { prototype: HTMLIonImgElement; new (): HTMLIonImgElement; }; + interface HTMLIonInfiniteScrollElementEventMap { + "ionInfinite": void; + } interface HTMLIonInfiniteScrollElement extends Components.IonInfiniteScroll, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonInfiniteScrollElement, ev: IonInfiniteScrollCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonInfiniteScrollElement, ev: IonInfiniteScrollCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonInfiniteScrollElement: { prototype: HTMLIonInfiniteScrollElement; @@ -3625,7 +3800,22 @@ declare global { prototype: HTMLIonInfiniteScrollContentElement; new (): HTMLIonInfiniteScrollContentElement; }; + interface HTMLIonInputElementEventMap { + "ionInput": InputInputEventDetail; + "ionChange": InputChangeEventDetail; + "ionBlur": FocusEvent; + "ionFocus": FocusEvent; + "ionStyle": StyleEventDetail; + } interface HTMLIonInputElement extends Components.IonInput, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonInputElement, ev: IonInputCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonInputElement, ev: IonInputCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonInputElement: { prototype: HTMLIonInputElement; @@ -3655,19 +3845,53 @@ declare global { prototype: HTMLIonItemOptionElement; new (): HTMLIonItemOptionElement; }; + interface HTMLIonItemOptionsElementEventMap { + "ionSwipe": any; + } interface HTMLIonItemOptionsElement extends Components.IonItemOptions, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonItemOptionsElement, ev: IonItemOptionsCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonItemOptionsElement, ev: IonItemOptionsCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonItemOptionsElement: { prototype: HTMLIonItemOptionsElement; new (): HTMLIonItemOptionsElement; }; + interface HTMLIonItemSlidingElementEventMap { + "ionDrag": any; + } interface HTMLIonItemSlidingElement extends Components.IonItemSliding, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonItemSlidingElement, ev: IonItemSlidingCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonItemSlidingElement, ev: IonItemSlidingCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonItemSlidingElement: { prototype: HTMLIonItemSlidingElement; new (): HTMLIonItemSlidingElement; }; + interface HTMLIonLabelElementEventMap { + "ionColor": StyleEventDetail; + "ionStyle": StyleEventDetail; + } interface HTMLIonLabelElement extends Components.IonLabel, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonLabelElement, ev: IonLabelCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonLabelElement, ev: IonLabelCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonLabelElement: { prototype: HTMLIonLabelElement; @@ -3685,13 +3909,46 @@ declare global { prototype: HTMLIonListHeaderElement; new (): HTMLIonListHeaderElement; }; + interface HTMLIonLoadingElementEventMap { + "ionLoadingDidPresent": void; + "ionLoadingWillPresent": void; + "ionLoadingWillDismiss": OverlayEventDetail; + "ionLoadingDidDismiss": OverlayEventDetail; + "didPresent": void; + "willPresent": void; + "willDismiss": OverlayEventDetail; + "didDismiss": OverlayEventDetail; + } interface HTMLIonLoadingElement extends Components.IonLoading, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonLoadingElement, ev: IonLoadingCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonLoadingElement, ev: IonLoadingCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonLoadingElement: { prototype: HTMLIonLoadingElement; new (): HTMLIonLoadingElement; }; + interface HTMLIonMenuElementEventMap { + "ionWillOpen": void; + "ionWillClose": void; + "ionDidOpen": void; + "ionDidClose": void; + "ionMenuChange": MenuChangeEventDetail; + } interface HTMLIonMenuElement extends Components.IonMenu, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonMenuElement, ev: IonMenuCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonMenuElement, ev: IonMenuCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonMenuElement: { prototype: HTMLIonMenuElement; @@ -3709,13 +3966,46 @@ declare global { prototype: HTMLIonMenuToggleElement; new (): HTMLIonMenuToggleElement; }; + interface HTMLIonModalElementEventMap { + "ionModalDidPresent": void; + "ionModalWillPresent": void; + "ionModalWillDismiss": OverlayEventDetail; + "ionModalDidDismiss": OverlayEventDetail; + "ionBreakpointDidChange": ModalBreakpointChangeEventDetail; + "didPresent": void; + "willPresent": void; + "willDismiss": OverlayEventDetail; + "didDismiss": OverlayEventDetail; + "ionMount": void; + } interface HTMLIonModalElement extends Components.IonModal, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonModalElement, ev: IonModalCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonModalElement, ev: IonModalCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonModalElement: { prototype: HTMLIonModalElement; new (): HTMLIonModalElement; }; + interface HTMLIonNavElementEventMap { + "ionNavWillLoad": void; + "ionNavWillChange": void; + "ionNavDidChange": void; + } interface HTMLIonNavElement extends Components.IonNav, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonNavElement, ev: IonNavCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonNavElement, ev: IonNavCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonNavElement: { prototype: HTMLIonNavElement; @@ -3733,31 +4023,101 @@ declare global { prototype: HTMLIonNoteElement; new (): HTMLIonNoteElement; }; + interface HTMLIonPickerElementEventMap { + "ionPickerDidPresent": void; + "ionPickerWillPresent": void; + "ionPickerWillDismiss": OverlayEventDetail; + "ionPickerDidDismiss": OverlayEventDetail; + "didPresent": void; + "willPresent": void; + "willDismiss": OverlayEventDetail; + "didDismiss": OverlayEventDetail; + } interface HTMLIonPickerElement extends Components.IonPicker, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonPickerElement, ev: IonPickerCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonPickerElement, ev: IonPickerCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonPickerElement: { prototype: HTMLIonPickerElement; new (): HTMLIonPickerElement; }; + interface HTMLIonPickerColumnElementEventMap { + "ionPickerColChange": PickerColumn; + } interface HTMLIonPickerColumnElement extends Components.IonPickerColumn, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonPickerColumnElement, ev: IonPickerColumnCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonPickerColumnElement, ev: IonPickerColumnCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonPickerColumnElement: { prototype: HTMLIonPickerColumnElement; new (): HTMLIonPickerColumnElement; }; + interface HTMLIonPickerColumnInternalElementEventMap { + "ionChange": PickerColumnItem; + } interface HTMLIonPickerColumnInternalElement extends Components.IonPickerColumnInternal, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonPickerColumnInternalElement, ev: IonPickerColumnInternalCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonPickerColumnInternalElement, ev: IonPickerColumnInternalCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonPickerColumnInternalElement: { prototype: HTMLIonPickerColumnInternalElement; new (): HTMLIonPickerColumnInternalElement; }; + interface HTMLIonPickerInternalElementEventMap { + "ionInputModeChange": PickerInternalChangeEventDetail; + } interface HTMLIonPickerInternalElement extends Components.IonPickerInternal, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonPickerInternalElement, ev: IonPickerInternalCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonPickerInternalElement, ev: IonPickerInternalCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonPickerInternalElement: { prototype: HTMLIonPickerInternalElement; new (): HTMLIonPickerInternalElement; }; + interface HTMLIonPopoverElementEventMap { + "ionPopoverDidPresent": void; + "ionPopoverWillPresent": void; + "ionPopoverWillDismiss": OverlayEventDetail; + "ionPopoverDidDismiss": OverlayEventDetail; + "didPresent": void; + "willPresent": void; + "willDismiss": OverlayEventDetail; + "didDismiss": OverlayEventDetail; + "ionMount": void; + } interface HTMLIonPopoverElement extends Components.IonPopover, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonPopoverElement, ev: IonPopoverCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonPopoverElement, ev: IonPopoverCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonPopoverElement: { prototype: HTMLIonPopoverElement; @@ -3769,25 +4129,80 @@ declare global { prototype: HTMLIonProgressBarElement; new (): HTMLIonProgressBarElement; }; + interface HTMLIonRadioElementEventMap { + "ionStyle": StyleEventDetail; + "ionFocus": void; + "ionBlur": void; + } interface HTMLIonRadioElement extends Components.IonRadio, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonRadioElement, ev: IonRadioCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonRadioElement, ev: IonRadioCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonRadioElement: { prototype: HTMLIonRadioElement; new (): HTMLIonRadioElement; }; + interface HTMLIonRadioGroupElementEventMap { + "ionChange": RadioGroupChangeEventDetail; + "ionValueChange": RadioGroupChangeEventDetail; + } interface HTMLIonRadioGroupElement extends Components.IonRadioGroup, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonRadioGroupElement, ev: IonRadioGroupCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonRadioGroupElement, ev: IonRadioGroupCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonRadioGroupElement: { prototype: HTMLIonRadioGroupElement; new (): HTMLIonRadioGroupElement; }; + interface HTMLIonRangeElementEventMap { + "ionChange": RangeChangeEventDetail; + "ionInput": RangeChangeEventDetail; + "ionStyle": StyleEventDetail; + "ionFocus": void; + "ionBlur": void; + "ionKnobMoveStart": RangeKnobMoveStartEventDetail; + "ionKnobMoveEnd": RangeKnobMoveEndEventDetail; + } interface HTMLIonRangeElement extends Components.IonRange, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonRangeElement, ev: IonRangeCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonRangeElement, ev: IonRangeCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonRangeElement: { prototype: HTMLIonRangeElement; new (): HTMLIonRangeElement; }; + interface HTMLIonRefresherElementEventMap { + "ionRefresh": RefresherEventDetail; + "ionPull": void; + "ionStart": void; + } interface HTMLIonRefresherElement extends Components.IonRefresher, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonRefresherElement, ev: IonRefresherCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonRefresherElement, ev: IonRefresherCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonRefresherElement: { prototype: HTMLIonRefresherElement; @@ -3805,7 +4220,18 @@ declare global { prototype: HTMLIonReorderElement; new (): HTMLIonReorderElement; }; + interface HTMLIonReorderGroupElementEventMap { + "ionItemReorder": ItemReorderEventDetail; + } interface HTMLIonReorderGroupElement extends Components.IonReorderGroup, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonReorderGroupElement, ev: IonReorderGroupCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonReorderGroupElement, ev: IonReorderGroupCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonReorderGroupElement: { prototype: HTMLIonReorderGroupElement; @@ -3817,19 +4243,53 @@ declare global { prototype: HTMLIonRippleEffectElement; new (): HTMLIonRippleEffectElement; }; + interface HTMLIonRouteElementEventMap { + "ionRouteDataChanged": any; + } interface HTMLIonRouteElement extends Components.IonRoute, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonRouteElement, ev: IonRouteCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonRouteElement, ev: IonRouteCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonRouteElement: { prototype: HTMLIonRouteElement; new (): HTMLIonRouteElement; }; + interface HTMLIonRouteRedirectElementEventMap { + "ionRouteRedirectChanged": any; + } interface HTMLIonRouteRedirectElement extends Components.IonRouteRedirect, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonRouteRedirectElement, ev: IonRouteRedirectCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonRouteRedirectElement, ev: IonRouteRedirectCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonRouteRedirectElement: { prototype: HTMLIonRouteRedirectElement; new (): HTMLIonRouteRedirectElement; }; + interface HTMLIonRouterElementEventMap { + "ionRouteWillChange": RouterEventDetail; + "ionRouteDidChange": RouterEventDetail; + } interface HTMLIonRouterElement extends Components.IonRouter, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonRouterElement, ev: IonRouterCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonRouterElement, ev: IonRouterCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonRouterElement: { prototype: HTMLIonRouterElement; @@ -3841,7 +4301,20 @@ declare global { prototype: HTMLIonRouterLinkElement; new (): HTMLIonRouterLinkElement; }; + interface HTMLIonRouterOutletElementEventMap { + "ionNavWillLoad": void; + "ionNavWillChange": void; + "ionNavDidChange": void; + } interface HTMLIonRouterOutletElement extends Components.IonRouterOutlet, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonRouterOutletElement, ev: IonRouterOutletCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonRouterOutletElement, ev: IonRouterOutletCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonRouterOutletElement: { prototype: HTMLIonRouterOutletElement; @@ -3853,13 +4326,43 @@ declare global { prototype: HTMLIonRowElement; new (): HTMLIonRowElement; }; + interface HTMLIonSearchbarElementEventMap { + "ionInput": SearchbarInputEventDetail; + "ionChange": SearchbarChangeEventDetail; + "ionCancel": void; + "ionClear": void; + "ionBlur": void; + "ionFocus": void; + "ionStyle": StyleEventDetail; + } interface HTMLIonSearchbarElement extends Components.IonSearchbar, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonSearchbarElement, ev: IonSearchbarCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonSearchbarElement, ev: IonSearchbarCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonSearchbarElement: { prototype: HTMLIonSearchbarElement; new (): HTMLIonSearchbarElement; }; + interface HTMLIonSegmentElementEventMap { + "ionChange": SegmentChangeEventDetail; + "ionSelect": SegmentChangeEventDetail; + "ionStyle": StyleEventDetail; + } interface HTMLIonSegmentElement extends Components.IonSegment, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonSegmentElement, ev: IonSegmentCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonSegmentElement, ev: IonSegmentCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonSegmentElement: { prototype: HTMLIonSegmentElement; @@ -3871,7 +4374,23 @@ declare global { prototype: HTMLIonSegmentButtonElement; new (): HTMLIonSegmentButtonElement; }; + interface HTMLIonSelectElementEventMap { + "ionChange": SelectChangeEventDetail; + "ionCancel": void; + "ionDismiss": void; + "ionFocus": void; + "ionBlur": void; + "ionStyle": StyleEventDetail; + } interface HTMLIonSelectElement extends Components.IonSelect, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonSelectElement, ev: IonSelectCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonSelectElement, ev: IonSelectCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonSelectElement: { prototype: HTMLIonSelectElement; @@ -3889,7 +4408,18 @@ declare global { prototype: HTMLIonSelectPopoverElement; new (): HTMLIonSelectPopoverElement; }; + interface HTMLIonSkeletonTextElementEventMap { + "ionStyle": StyleEventDetail; + } interface HTMLIonSkeletonTextElement extends Components.IonSkeletonText, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonSkeletonTextElement, ev: IonSkeletonTextCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonSkeletonTextElement, ev: IonSkeletonTextCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonSkeletonTextElement: { prototype: HTMLIonSkeletonTextElement; @@ -3901,7 +4431,18 @@ declare global { prototype: HTMLIonSpinnerElement; new (): HTMLIonSpinnerElement; }; + interface HTMLIonSplitPaneElementEventMap { + "ionSplitPaneVisible": { visible: boolean }; + } interface HTMLIonSplitPaneElement extends Components.IonSplitPane, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonSplitPaneElement, ev: IonSplitPaneCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonSplitPaneElement, ev: IonSplitPaneCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonSplitPaneElement: { prototype: HTMLIonSplitPaneElement; @@ -3913,19 +4454,55 @@ declare global { prototype: HTMLIonTabElement; new (): HTMLIonTabElement; }; + interface HTMLIonTabBarElementEventMap { + "ionTabBarChanged": TabBarChangedEventDetail; + "ionTabBarLoaded": void; + } interface HTMLIonTabBarElement extends Components.IonTabBar, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonTabBarElement, ev: IonTabBarCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonTabBarElement, ev: IonTabBarCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonTabBarElement: { prototype: HTMLIonTabBarElement; new (): HTMLIonTabBarElement; }; + interface HTMLIonTabButtonElementEventMap { + "ionTabButtonClick": TabButtonClickEventDetail; + } interface HTMLIonTabButtonElement extends Components.IonTabButton, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonTabButtonElement, ev: IonTabButtonCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonTabButtonElement, ev: IonTabButtonCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonTabButtonElement: { prototype: HTMLIonTabButtonElement; new (): HTMLIonTabButtonElement; }; + interface HTMLIonTabsElementEventMap { + "ionNavWillLoad": void; + "ionTabsWillChange": { tab: string }; + "ionTabsDidChange": { tab: string }; + } interface HTMLIonTabsElement extends Components.IonTabs, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonTabsElement, ev: IonTabsCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonTabsElement, ev: IonTabsCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonTabsElement: { prototype: HTMLIonTabsElement; @@ -3937,7 +4514,22 @@ declare global { prototype: HTMLIonTextElement; new (): HTMLIonTextElement; }; + interface HTMLIonTextareaElementEventMap { + "ionChange": TextareaChangeEventDetail; + "ionInput": TextareaInputEventDetail; + "ionStyle": StyleEventDetail; + "ionBlur": FocusEvent; + "ionFocus": FocusEvent; + } interface HTMLIonTextareaElement extends Components.IonTextarea, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonTextareaElement, ev: IonTextareaCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonTextareaElement, ev: IonTextareaCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonTextareaElement: { prototype: HTMLIonTextareaElement; @@ -3949,19 +4541,62 @@ declare global { prototype: HTMLIonThumbnailElement; new (): HTMLIonThumbnailElement; }; + interface HTMLIonTitleElementEventMap { + "ionStyle": StyleEventDetail; + } interface HTMLIonTitleElement extends Components.IonTitle, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonTitleElement, ev: IonTitleCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonTitleElement, ev: IonTitleCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonTitleElement: { prototype: HTMLIonTitleElement; new (): HTMLIonTitleElement; }; + interface HTMLIonToastElementEventMap { + "ionToastDidPresent": void; + "ionToastWillPresent": void; + "ionToastWillDismiss": OverlayEventDetail; + "ionToastDidDismiss": OverlayEventDetail; + "didPresent": void; + "willPresent": void; + "willDismiss": OverlayEventDetail; + "didDismiss": OverlayEventDetail; + } interface HTMLIonToastElement extends Components.IonToast, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonToastElement, ev: IonToastCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonToastElement, ev: IonToastCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonToastElement: { prototype: HTMLIonToastElement; new (): HTMLIonToastElement; }; + interface HTMLIonToggleElementEventMap { + "ionChange": ToggleChangeEventDetail; + "ionFocus": void; + "ionBlur": void; + "ionStyle": StyleEventDetail; + } interface HTMLIonToggleElement extends Components.IonToggle, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLIonToggleElement, ev: IonToggleCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLIonToggleElement, ev: IonToggleCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLIonToggleElement: { prototype: HTMLIonToggleElement; diff --git a/packages/angular/src/directives/proxies.ts b/packages/angular/src/directives/proxies.ts index 2e4766de237..83cae5db284 100644 --- a/packages/angular/src/directives/proxies.ts +++ b/packages/angular/src/directives/proxies.ts @@ -1535,14 +1535,14 @@ export declare interface IonRadio extends Components.IonRadio { @ProxyCmp({ - inputs: ['allowEmptySelection', 'name', 'value'] + inputs: ['allowEmptySelection', 'compareWith', 'name', 'value'] }) @Component({ selector: 'ion-radio-group', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['allowEmptySelection', 'name', 'value'], + inputs: ['allowEmptySelection', 'compareWith', 'name', 'value'], }) export class IonRadioGroup { protected el: HTMLElement; diff --git a/packages/vue/src/proxies.ts b/packages/vue/src/proxies.ts index de9aebb8b92..e81c9d23279 100644 --- a/packages/vue/src/proxies.ts +++ b/packages/vue/src/proxies.ts @@ -596,6 +596,7 @@ export const IonRadio = /*@__PURE__*/ defineContainer('ion-radio-group', defineIonRadioGroup, [ 'allowEmptySelection', + 'compareWith', 'name', 'value', 'ionChange', From 6f5cbc8a7c59296370387e8e3eca5de603192071 Mon Sep 17 00:00:00 2001 From: Shawn Taylor Date: Fri, 3 Nov 2023 12:51:29 -0400 Subject: [PATCH 6/9] Improve tests --- .../radio-group/test/compare-with/index.html | 11 +++-- .../test/compare-with/radio-group.e2e.ts | 42 ++++++++++++++----- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/core/src/components/radio-group/test/compare-with/index.html b/core/src/components/radio-group/test/compare-with/index.html index a2f7776e7eb..d29a4a9b818 100644 --- a/core/src/components/radio-group/test/compare-with/index.html +++ b/core/src/components/radio-group/test/compare-with/index.html @@ -32,6 +32,11 @@ Compare with Function + + + null compare with + + @@ -51,14 +56,12 @@ }, ]; - const radioGroupWithString = document.querySelector('#compareWithString'); - radioGroupWithString.value = options[1]; - const radioGroupWithFn = document.querySelector('#compareWithFn'); radioGroupWithFn.compareWith = (a, b) => a.value === b.value; - radioGroupWithFn.value = options[1]; document.querySelectorAll('ion-radio-group').forEach((radioGroup) => { + radioGroup.value = options[1]; + options.forEach((option) => { const radio = document.createElement('ion-radio'); diff --git a/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts b/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts index 70aa9706caa..3ff85acf6a4 100644 --- a/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts +++ b/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts @@ -11,10 +11,15 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => const radioGroupWithString = page.locator('#compareWithString'); + const lastRadio = radioGroupWithString.locator('ion-radio').last(); + await lastRadio.click(); + await page.waitForChanges(); + await expect(radioGroupWithString).toHaveJSProperty('value', { - label: 'Blue', - value: 'blue', + label: 'Green', + value: 'green', }); + await expect(lastRadio).toHaveAttribute('aria-checked', 'true'); }); test('should correctly set value when using compareWith function', async ({ page }) => { @@ -22,25 +27,31 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => const radioGroupWithFn = page.locator('#compareWithFn'); + const lastRadio = radioGroupWithFn.locator('ion-radio').last(); + await lastRadio.click(); + await page.waitForChanges(); + await expect(radioGroupWithFn).toHaveJSProperty('value', { - label: 'Blue', - value: 'blue', + label: 'Green', + value: 'green', }); + await expect(lastRadio).toHaveAttribute('aria-checked', 'true'); }); - test('should correctly set value to an object when clicked', async ({ page }) => { + test('should correctly set value when using null compareWith', async ({ page }) => { await page.goto('/src/components/radio-group/test/compare-with', config); - const radioGroupWithFn = page.locator('#compareWithFn'); + const radioGroupWithNull = page.locator('#compareWithNull'); - const firstRadio = radioGroupWithFn.locator('ion-radio').first(); - await firstRadio.click(); + const lastRadio = radioGroupWithNull.locator('ion-radio').last(); + await lastRadio.click(); await page.waitForChanges(); - await expect(radioGroupWithFn).toHaveJSProperty('value', { - label: 'Red', - value: 'red', + await expect(radioGroupWithNull).toHaveJSProperty('value', { + label: 'Green', + value: 'green', }); + await expect(lastRadio).toHaveAttribute('aria-checked', 'true'); }); test('should work with different parameter types', async ({ page }) => { @@ -81,11 +92,20 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => config ); + const radioGroup = page.locator('ion-radio-group'); const radios = page.locator('ion-radio'); await expect(radios.nth(0)).toHaveAttribute('aria-checked', 'false'); await expect(radios.nth(1)).toHaveAttribute('aria-checked', 'false'); await expect(radios.nth(2)).toHaveAttribute('aria-checked', 'true'); + + await radios.nth(0).click(); + await page.waitForChanges(); + + await expect(radios.nth(0)).toHaveAttribute('aria-checked', 'true'); + await expect(radios.nth(1)).toHaveAttribute('aria-checked', 'false'); + await expect(radios.nth(2)).toHaveAttribute('aria-checked', 'false'); + await expect(radioGroup).toHaveJSProperty('value', 1); }); }); }); From 02502c21794260f57e78b7fa78f2367e8e6b7b3e Mon Sep 17 00:00:00 2001 From: Shawn Taylor Date: Fri, 3 Nov 2023 19:40:34 -0400 Subject: [PATCH 7/9] Improve documentation in code --- core/src/components.d.ts | 8 ++++---- core/src/components/radio-group/radio-group.tsx | 2 +- core/src/components/select/select.tsx | 2 +- core/src/utils/forms/compare-with-utils.ts | 11 +++++++++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/core/src/components.d.ts b/core/src/components.d.ts index c73a60bcbea..791fbfc9b9e 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -2266,7 +2266,7 @@ export namespace Components { */ "allowEmptySelection": boolean; /** - * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-radio-group. When not specified, the default behavior will use object equality (===) for comparison. + * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-radio-group. When not specified, the default behavior will use strict equality (===) for comparison. */ "compareWith"?: string | RadioGroupCompareFn | null; /** @@ -2688,7 +2688,7 @@ export namespace Components { */ "color"?: Color; /** - * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-select. When not specified, the default behavior will use object equality (===) for comparison. + * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-select. When not specified, the default behavior will use strict equality (===) for comparison. */ "compareWith"?: string | SelectCompareFn | null; /** @@ -6946,7 +6946,7 @@ declare namespace LocalJSX { */ "allowEmptySelection"?: boolean; /** - * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-radio-group. When not specified, the default behavior will use object equality (===) for comparison. + * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-radio-group. When not specified, the default behavior will use strict equality (===) for comparison. */ "compareWith"?: string | RadioGroupCompareFn | null; /** @@ -7431,7 +7431,7 @@ declare namespace LocalJSX { */ "color"?: Color; /** - * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-select. When not specified, the default behavior will use object equality (===) for comparison. + * This property allows developers to specify a custom function or property name for comparing objects when determining the selected option in the ion-select. When not specified, the default behavior will use strict equality (===) for comparison. */ "compareWith"?: string | SelectCompareFn | null; /** diff --git a/core/src/components/radio-group/radio-group.tsx b/core/src/components/radio-group/radio-group.tsx index 31cfda38b32..2bf0dd5a11a 100644 --- a/core/src/components/radio-group/radio-group.tsx +++ b/core/src/components/radio-group/radio-group.tsx @@ -24,7 +24,7 @@ export class RadioGroup implements ComponentInterface { /** * This property allows developers to specify a custom function or property * name for comparing objects when determining the selected option in the - * ion-radio-group. When not specified, the default behavior will use object + * ion-radio-group. When not specified, the default behavior will use strict * equality (===) for comparison. */ @Prop() compareWith?: string | RadioGroupCompareFn | null; diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index ade6f79de62..6eaeb551486 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -84,7 +84,7 @@ export class Select implements ComponentInterface { /** * This property allows developers to specify a custom function or property * name for comparing objects when determining the selected option in the - * ion-select. When not specified, the default behavior will use object + * ion-select. When not specified, the default behavior will use strict * equality (===) for comparison. */ @Prop() compareWith?: string | SelectCompareFn | null; diff --git a/core/src/utils/forms/compare-with-utils.ts b/core/src/utils/forms/compare-with-utils.ts index 36cff8eac8f..18c32ec3c21 100644 --- a/core/src/utils/forms/compare-with-utils.ts +++ b/core/src/utils/forms/compare-with-utils.ts @@ -1,5 +1,12 @@ type CompareFn = (currentValue: any, compareValue: any) => boolean; +/** + * Uses the compareWith param to compare two values to determine if they are equal. + * + * @param currentValue A current value of the control. + * @param compareValue The value to compare against. + * @param compareWith The function or property name to use to compare values. + */ export const compareOptions = ( currentValue: any, compareValue: any, @@ -15,11 +22,11 @@ export const compareOptions = ( }; /** - * Compares a value against the current value to determine if it is selected. + * Compares a value against the current value(s) to determine if it is selected. * * @param currentValue The current value of the control. * @param compareValue The value to compare against. - * @param compareWith The function to use to compare values. + * @param compareWith The function or property name to use to compare values. */ export const isOptionSelected = ( currentValue: any[] | any, From 569ef651ebcc2726034f31862cc4edd7124f8f6e Mon Sep 17 00:00:00 2001 From: Shawn Taylor Date: Fri, 3 Nov 2023 20:43:56 -0400 Subject: [PATCH 8/9] Refactor to spec tests --- .../radio-group/test/compare-with/index.html | 5 - .../test/compare-with/radio-group.e2e.ts | 111 ------------------ .../radio-group/test/radio-group.spec.tsx | 111 ++++++++++++++++++ 3 files changed, 111 insertions(+), 116 deletions(-) delete mode 100644 core/src/components/radio-group/test/compare-with/radio-group.e2e.ts create mode 100644 core/src/components/radio-group/test/radio-group.spec.tsx diff --git a/core/src/components/radio-group/test/compare-with/index.html b/core/src/components/radio-group/test/compare-with/index.html index d29a4a9b818..71a019c1ad5 100644 --- a/core/src/components/radio-group/test/compare-with/index.html +++ b/core/src/components/radio-group/test/compare-with/index.html @@ -32,11 +32,6 @@ Compare with Function - - - null compare with - - diff --git a/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts b/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts deleted file mode 100644 index 3ff85acf6a4..00000000000 --- a/core/src/components/radio-group/test/compare-with/radio-group.e2e.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { expect } from '@playwright/test'; -import { configs, test } from '@utils/test/playwright'; - -/** - * This behavior does not vary across modes/directions. - */ -configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { - test.describe(title('radio-group: compare-with'), () => { - test('should correctly set value when using compareWith string', async ({ page }) => { - await page.goto('/src/components/radio-group/test/compare-with', config); - - const radioGroupWithString = page.locator('#compareWithString'); - - const lastRadio = radioGroupWithString.locator('ion-radio').last(); - await lastRadio.click(); - await page.waitForChanges(); - - await expect(radioGroupWithString).toHaveJSProperty('value', { - label: 'Green', - value: 'green', - }); - await expect(lastRadio).toHaveAttribute('aria-checked', 'true'); - }); - - test('should correctly set value when using compareWith function', async ({ page }) => { - await page.goto('/src/components/radio-group/test/compare-with', config); - - const radioGroupWithFn = page.locator('#compareWithFn'); - - const lastRadio = radioGroupWithFn.locator('ion-radio').last(); - await lastRadio.click(); - await page.waitForChanges(); - - await expect(radioGroupWithFn).toHaveJSProperty('value', { - label: 'Green', - value: 'green', - }); - await expect(lastRadio).toHaveAttribute('aria-checked', 'true'); - }); - - test('should correctly set value when using null compareWith', async ({ page }) => { - await page.goto('/src/components/radio-group/test/compare-with', config); - - const radioGroupWithNull = page.locator('#compareWithNull'); - - const lastRadio = radioGroupWithNull.locator('ion-radio').last(); - await lastRadio.click(); - await page.waitForChanges(); - - await expect(radioGroupWithNull).toHaveJSProperty('value', { - label: 'Green', - value: 'green', - }); - await expect(lastRadio).toHaveAttribute('aria-checked', 'true'); - }); - - test('should work with different parameter types', async ({ page }) => { - test.info().annotations.push({ - type: 'issue', - description: 'https://github.com/ionic-team/ionic-framework/issues/25759', - }); - - await page.setContent( - ` - - - - `, - config - ); - - const radioGroup = page.locator('ion-radio-group'); - const radios = page.locator('ion-radio'); - - await expect(radios.nth(0)).toHaveAttribute('aria-checked', 'false'); - await expect(radios.nth(1)).toHaveAttribute('aria-checked', 'false'); - await expect(radios.nth(2)).toHaveAttribute('aria-checked', 'true'); - - await radios.nth(0).click(); - await page.waitForChanges(); - - await expect(radios.nth(0)).toHaveAttribute('aria-checked', 'true'); - await expect(radios.nth(1)).toHaveAttribute('aria-checked', 'false'); - await expect(radios.nth(2)).toHaveAttribute('aria-checked', 'false'); - await expect(radioGroup).toHaveJSProperty('value', 1); - }); - }); -}); diff --git a/core/src/components/radio-group/test/radio-group.spec.tsx b/core/src/components/radio-group/test/radio-group.spec.tsx new file mode 100644 index 00000000000..fdd6c644267 --- /dev/null +++ b/core/src/components/radio-group/test/radio-group.spec.tsx @@ -0,0 +1,111 @@ +import { h } from '@stencil/core'; +import { newSpecPage } from '@stencil/core/testing'; + +import { Radio } from '../../radio/radio'; +import { RadioGroup } from '../radio-group'; + +describe('ion-radio-group', () => { + it('should correctly set value when using compareWith string', async () => { + const page = await newSpecPage({ + components: [Radio, RadioGroup], + template: () => ( + + Red + Blue + Green + + ), + }); + + const radioGroup = page.body.querySelector('ion-radio-group')!; + const radios = document.querySelectorAll('ion-radio')!; + + await radios[2].click(); + await page.waitForChanges(); + + expect(radios[2].getAttribute('aria-checked')).toBe('true'); + expect(radioGroup.value).toEqual({ + label: 'Green', + value: 'green', + }); + }); + + it('should correctly set value when using compareWith function', async () => { + const page = await newSpecPage({ + components: [Radio, RadioGroup], + template: () => ( + + Red + Blue + Green + + ), + }); + + const radioGroup = page.body.querySelector('ion-radio-group')!; + const radios = document.querySelectorAll('ion-radio')!; + radioGroup.compareWith = (a, b) => a.value === b.value; + + await radios[2].click(); + await page.waitForChanges(); + + expect(radios[2].getAttribute('aria-checked')).toBe('true'); + expect(radioGroup.value).toEqual({ + label: 'Green', + value: 'green', + }); + }); + + it('should correctly set value when using compareWith null', async () => { + const page = await newSpecPage({ + components: [RadioGroup, Radio], + template: () => ( + + Red +
+ Blue +
+ Green +
+ ), + }); + + const radioGroup = page.body.querySelector('ion-radio-group')!; + const radios = document.querySelectorAll('ion-radio')!; + + await radios[2].click(); + await page.waitForChanges(); + + expect(radios[2].getAttribute('aria-checked')).toBe('true'); + expect(radioGroup.value).toEqual('green'); + }); + + it('should work with different parameter types', async () => { + const page = await newSpecPage({ + components: [Radio, RadioGroup], + template: () => ( + + Option #1 + Option #2 + Option #3 + + ), + }); + + const radioGroup = page.body.querySelector('ion-radio-group')!; + radioGroup.compareWith = (val1, val2) => { + // convert val1 to a number + return +val1 === val2; + }; + + const radios = document.querySelectorAll('ion-radio')!; + + await expect(radios[1].getAttribute('aria-checked')).toBe('true'); + + await radios[2].click(); + await page.waitForChanges(); + + expect(radios[2].getAttribute('aria-checked')).toBe('true'); + expect(radioGroup.value).toEqual(3); + }); +}); From cdb58d373bf8b2d8243a628e2816232f31fbb5d4 Mon Sep 17 00:00:00 2001 From: Shawn Taylor Date: Wed, 8 Nov 2023 09:12:04 -0500 Subject: [PATCH 9/9] Update core/src/utils/forms/compare-with-utils.ts Co-authored-by: Liam DeBeasi --- core/src/utils/forms/compare-with-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/utils/forms/compare-with-utils.ts b/core/src/utils/forms/compare-with-utils.ts index 18c32ec3c21..2ab1fd0237b 100644 --- a/core/src/utils/forms/compare-with-utils.ts +++ b/core/src/utils/forms/compare-with-utils.ts @@ -3,7 +3,7 @@ type CompareFn = (currentValue: any, compareValue: any) => boolean; /** * Uses the compareWith param to compare two values to determine if they are equal. * - * @param currentValue A current value of the control. + * @param currentValue The current value of the control. * @param compareValue The value to compare against. * @param compareWith The function or property name to use to compare values. */