From 2d71266f118b64acff3df7ccb445fcee048ab063 Mon Sep 17 00:00:00 2001
From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Date: Fri, 25 Apr 2025 14:53:19 -0400
Subject: [PATCH 01/11] fix(item): only trigger one click event when clicking
on the padding of item
---
core/src/components/item/item.tsx | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/core/src/components/item/item.tsx b/core/src/components/item/item.tsx
index 6091e8b1cf8..d9adfdda2ea 100644
--- a/core/src/components/item/item.tsx
+++ b/core/src/components/item/item.tsx
@@ -286,6 +286,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
if (firstInteractive !== undefined && !multipleInputs) {
const path = ev.composedPath();
const target = path[0] as HTMLElement;
+
if (ev.isTrusted) {
/**
* Dispatches a click event to the first interactive element,
@@ -306,6 +307,12 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
(firstInteractive as HTMLIonInputElement | HTMLIonTextareaElement).setFocus();
} else {
firstInteractive.click();
+ /**
+ * Stop the item event from being triggered
+ * as the firstInteractive click event will also
+ * trigger the item click event.
+ */
+ ev.stopImmediatePropagation();
}
}
}
From 015bff92bef1f8c8ef8b6ce1c0e38507d6e11167 Mon Sep 17 00:00:00 2001
From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Date: Fri, 25 Apr 2025 15:32:17 -0400
Subject: [PATCH 02/11] test(many): add tests for firing click event on item
padding
---
.../checkbox/test/basic/checkbox.e2e.ts | 23 ------
.../checkbox/test/item/checkbox.e2e.ts | 67 +++++++++++++++++
.../components/radio/test/item/radio.e2e.ts | 48 +++++++++++-
.../select/test/basic/select.e2e.ts | 28 -------
.../components/select/test/item/select.e2e.ts | 75 +++++++++++++++++++
.../components/toggle/test/item/toggle.e2e.ts | 48 +++++++++++-
6 files changed, 232 insertions(+), 57 deletions(-)
diff --git a/core/src/components/checkbox/test/basic/checkbox.e2e.ts b/core/src/components/checkbox/test/basic/checkbox.e2e.ts
index 957c6da31b8..1a41b339599 100644
--- a/core/src/components/checkbox/test/basic/checkbox.e2e.ts
+++ b/core/src/components/checkbox/test/basic/checkbox.e2e.ts
@@ -98,28 +98,5 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
await checkbox.evaluate((el: HTMLIonCheckboxElement) => (el.checked = true));
expect(ionChange).not.toHaveReceivedEvent();
});
-
- test('clicking padded space within item should click the checkbox', async ({ page }) => {
- await page.setContent(
- `
-
- Size
-
- `,
- config
- );
- const itemNative = page.locator('.item-native');
- const ionChange = await page.spyOnEvent('ionChange');
-
- // Clicks the padded space within the item
- await itemNative.click({
- position: {
- x: 5,
- y: 5,
- },
- });
-
- expect(ionChange).toHaveReceivedEvent();
- });
});
});
diff --git a/core/src/components/checkbox/test/item/checkbox.e2e.ts b/core/src/components/checkbox/test/item/checkbox.e2e.ts
index bdcf1892da2..341839739b1 100644
--- a/core/src/components/checkbox/test/item/checkbox.e2e.ts
+++ b/core/src/components/checkbox/test/item/checkbox.e2e.ts
@@ -127,3 +127,70 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
});
});
});
+
+configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
+ test.describe(title('checkbox: item functionality'), () => {
+ test('clicking padded space within item should click the checkbox', async ({ page }) => {
+ test.info().annotations.push({
+ type: 'issue',
+ description: 'https://github.com/ionic-team/ionic-framework/issues/27169',
+ });
+
+ await page.setContent(
+ `
+
+ Size
+
+ `,
+ config
+ );
+ const item = page.locator('ion-item');
+ const ionChange = await page.spyOnEvent('ionChange');
+
+ // Clicks the padded space within the item
+ await item.click({
+ position: {
+ x: 5,
+ y: 5,
+ },
+ });
+
+ expect(ionChange).toHaveReceivedEvent();
+ });
+
+ test('clicking padded space within item should fire one click event', async ({ page }) => {
+ test.info().annotations.push({
+ type: 'issue',
+ description: 'https://github.com/ionic-team/ionic-framework/issues/29758',
+ });
+
+ await page.setContent(
+ `
+
+
+ Checkbox
+
+
+ `,
+ config
+ );
+
+ const item = page.locator('ion-item');
+ const onClick = await page.spyOnEvent('click');
+
+ // Click the padding area (5px from left edge)
+ await item.click({
+ position: {
+ x: 5,
+ y: 5,
+ },
+ });
+
+ expect(onClick).toHaveReceivedEventTimes(1);
+
+ // Verify that the event target is the checkbox and not the item
+ const event = onClick.events[0];
+ expect((event.target as HTMLElement).tagName.toLowerCase()).toBe('ion-checkbox');
+ });
+ });
+});
diff --git a/core/src/components/radio/test/item/radio.e2e.ts b/core/src/components/radio/test/item/radio.e2e.ts
index 4fdf34bd4e1..8c9fd4be951 100644
--- a/core/src/components/radio/test/item/radio.e2e.ts
+++ b/core/src/components/radio/test/item/radio.e2e.ts
@@ -78,9 +78,16 @@ configs({ directions: ['ltr'], modes: ['md'] }).forEach(({ title, screenshot, co
await expect(list).toHaveScreenshot(screenshot(`radio-stacked-label-in-item`));
});
});
+});
- test.describe(title('radio: ionChange'), () => {
+configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
+ test.describe(title('radio: item functionality'), () => {
test('clicking padded space within item should click the radio', async ({ page }) => {
+ test.info().annotations.push({
+ type: 'issue',
+ description: 'https://github.com/ionic-team/ionic-framework/issues/27169',
+ });
+
await page.setContent(
`
@@ -93,11 +100,11 @@ configs({ directions: ['ltr'], modes: ['md'] }).forEach(({ title, screenshot, co
`,
config
);
- const itemNative = page.locator('.item-native');
+ const item = page.locator('ion-item');
const ionChange = await page.spyOnEvent('ionChange');
// Clicks the padded space within the item
- await itemNative.click({
+ await item.click({
position: {
x: 5,
y: 5,
@@ -106,5 +113,40 @@ configs({ directions: ['ltr'], modes: ['md'] }).forEach(({ title, screenshot, co
expect(ionChange).toHaveReceivedEvent();
});
+
+ test('clicking padded space within item should fire one click event', async ({ page }) => {
+ test.info().annotations.push({
+ type: 'issue',
+ description: 'https://github.com/ionic-team/ionic-framework/issues/29758',
+ });
+
+ await page.setContent(
+ `
+
+
+ Radio
+
+
+ `,
+ config
+ );
+
+ const item = page.locator('ion-item');
+ const onClick = await page.spyOnEvent('click');
+
+ // Click the padding area (5px from left edge)
+ await item.click({
+ position: {
+ x: 5,
+ y: 5,
+ },
+ });
+
+ expect(onClick).toHaveReceivedEventTimes(1);
+
+ // Verify that the event target is the radio and not the item
+ const event = onClick.events[0];
+ expect((event.target as HTMLElement).tagName.toLowerCase()).toBe('ion-radio');
+ });
});
});
diff --git a/core/src/components/select/test/basic/select.e2e.ts b/core/src/components/select/test/basic/select.e2e.ts
index d5a9c3d220f..63f1c8ca10a 100644
--- a/core/src/components/select/test/basic/select.e2e.ts
+++ b/core/src/components/select/test/basic/select.e2e.ts
@@ -294,34 +294,6 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
await select.evaluate((el: HTMLIonSelectElement) => (el.value = 'banana'));
await expect(ionChange).not.toHaveReceivedEvent();
});
-
- test('clicking padded space within item should click the select', async ({ page }) => {
- await page.setContent(
- `
-
-
- Apple
- Banana
-
-
- `,
- config
- );
- const itemNative = page.locator('.item-native');
- const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
-
- // Clicks the padded space within the item
- await itemNative.click({
- position: {
- x: 5,
- y: 5,
- },
- });
-
- await ionActionSheetDidPresent.next();
-
- expect(ionActionSheetDidPresent).toHaveReceivedEvent();
- });
});
});
diff --git a/core/src/components/select/test/item/select.e2e.ts b/core/src/components/select/test/item/select.e2e.ts
index 05ca3e4abb3..d0ad1d616d0 100644
--- a/core/src/components/select/test/item/select.e2e.ts
+++ b/core/src/components/select/test/item/select.e2e.ts
@@ -61,3 +61,78 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
});
});
});
+
+configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
+ test.describe(title('select: item functionality'), () => {
+ test('clicking padded space within item should click the select', async ({ page }) => {
+ test.info().annotations.push({
+ type: 'issue',
+ description: 'https://github.com/ionic-team/ionic-framework/issues/27169',
+ });
+
+ await page.setContent(
+ `
+
+
+ Apple
+ Banana
+
+
+ `,
+ config
+ );
+ const item = page.locator('ion-item');
+ const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
+
+ // Clicks the padded space within the item
+ await item.click({
+ position: {
+ x: 5,
+ y: 5,
+ },
+ });
+
+ await ionActionSheetDidPresent.next();
+
+ expect(ionActionSheetDidPresent).toHaveReceivedEvent();
+ });
+
+ test('clicking padded space within item should fire one click event', async ({ page }) => {
+ test.info().annotations.push({
+ type: 'issue',
+ description: 'https://github.com/ionic-team/ionic-framework/issues/29758',
+ });
+
+ await page.setContent(
+ `
+
+
+ Apple
+
+
+ `,
+ config
+ );
+
+ const item = page.locator('ion-item');
+ const onClick = await page.spyOnEvent('click');
+
+ // Click the padding area (5px from left edge)
+ await item.click({
+ position: {
+ x: 5,
+ y: 5,
+ },
+ });
+
+ expect(onClick).toHaveReceivedEventTimes(1);
+
+ // Verify that the event target is the select and not the item
+ const event = onClick.events[0];
+ expect((event.target as HTMLElement).tagName.toLowerCase()).toBe('ion-select');
+ });
+ });
+});
diff --git a/core/src/components/toggle/test/item/toggle.e2e.ts b/core/src/components/toggle/test/item/toggle.e2e.ts
index f5db0dab8ab..866a382494f 100644
--- a/core/src/components/toggle/test/item/toggle.e2e.ts
+++ b/core/src/components/toggle/test/item/toggle.e2e.ts
@@ -108,9 +108,16 @@ configs({ directions: ['ltr'], modes: ['md'] }).forEach(({ title, screenshot, co
await expect(list).toHaveScreenshot(screenshot(`toggle-stacked-label-in-item`));
});
});
+});
- test.describe(title('toggle: ionChange'), () => {
+configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
+ test.describe(title('toggle: item functionality'), () => {
test('clicking padded space within item should click the toggle', async ({ page }) => {
+ test.info().annotations.push({
+ type: 'issue',
+ description: 'https://github.com/ionic-team/ionic-framework/issues/27169',
+ });
+
await page.setContent(
`
@@ -119,7 +126,7 @@ configs({ directions: ['ltr'], modes: ['md'] }).forEach(({ title, screenshot, co
`,
config
);
- const itemNative = page.locator('.item-native');
+ const item = page.locator('ion-item');
const ionChange = await page.spyOnEvent('ionChange');
/**
@@ -132,7 +139,7 @@ configs({ directions: ['ltr'], modes: ['md'] }).forEach(({ title, screenshot, co
* 2. iOS is inconsistent in their implementation and other controls can be activated by clicking the label.
* 3. MD is consistent in their implementation and activates controls by clicking the label.
*/
- await itemNative.click({
+ await item.click({
position: {
x: 5,
y: 5,
@@ -141,5 +148,40 @@ configs({ directions: ['ltr'], modes: ['md'] }).forEach(({ title, screenshot, co
expect(ionChange).toHaveReceivedEvent();
});
+
+ test('clicking padded space within item should fire one click event', async ({ page }) => {
+ test.info().annotations.push({
+ type: 'issue',
+ description: 'https://github.com/ionic-team/ionic-framework/issues/29758',
+ });
+
+ await page.setContent(
+ `
+
+
+ Toggle
+
+
+ `,
+ config
+ );
+
+ const item = page.locator('ion-item');
+ const onClick = await page.spyOnEvent('click');
+
+ // Click the padding area (5px from left edge)
+ await item.click({
+ position: {
+ x: 5,
+ y: 5,
+ },
+ });
+
+ expect(onClick).toHaveReceivedEventTimes(1);
+
+ // Verify that the event target is the toggle and not the item
+ const event = onClick.events[0];
+ expect((event.target as HTMLElement).tagName.toLowerCase()).toBe('ion-toggle');
+ });
});
});
From 3cfcf2a4d42d3ee3ad72245e6471af5f55a86d74 Mon Sep 17 00:00:00 2001
From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
Date: Fri, 25 Apr 2025 15:34:04 -0400
Subject: [PATCH 03/11] test(many): add click listener to tests
---
core/src/components/checkbox/test/item/index.html | 10 ++++++++++
core/src/components/input/test/item/index.html | 10 ++++++++++
core/src/components/radio/test/item/index.html | 10 ++++++++++
core/src/components/select/test/item/index.html | 10 ++++++++++
core/src/components/textarea/test/item/index.html | 10 ++++++++++
core/src/components/toggle/test/item/index.html | 10 ++++++++++
6 files changed, 60 insertions(+)
diff --git a/core/src/components/checkbox/test/item/index.html b/core/src/components/checkbox/test/item/index.html
index b2fa0bdccd1..8692c4a022e 100644
--- a/core/src/components/checkbox/test/item/index.html
+++ b/core/src/components/checkbox/test/item/index.html
@@ -246,6 +246,16 @@ Multiline Label
+
+