fix(segment): change event fires when clicking (#27010)

resolves #27002
This commit is contained in:
Liam DeBeasi
2023-03-23 16:18:43 -04:00
committed by GitHub
parent 79ba8816f4
commit 3e0a905e81
2 changed files with 31 additions and 7 deletions

View File

@ -24,7 +24,6 @@ import type { SegmentChangeEventDetail } from './segment-interface';
}) })
export class Segment implements ComponentInterface { export class Segment implements ComponentInterface {
private gesture?: Gesture; private gesture?: Gesture;
private checked?: HTMLIonSegmentButtonElement;
// Value before the segment is dragged // Value before the segment is dragged
private valueBeforeGesture?: string; private valueBeforeGesture?: string;
@ -227,6 +226,10 @@ export class Segment implements ComponentInterface {
return Array.from(this.el.querySelectorAll('ion-segment-button')); return Array.from(this.el.querySelectorAll('ion-segment-button'));
} }
private get checked() {
return this.getButtons().find((button) => button.value === this.value);
}
/** /**
* The gesture blocks the segment button ripple. This * The gesture blocks the segment button ripple. This
* function adds the ripple based on the checked segment * function adds the ripple based on the checked segment
@ -341,9 +344,6 @@ export class Segment implements ComponentInterface {
const index = buttons.findIndex((button) => button.value === this.value); const index = buttons.findIndex((button) => button.value === this.value);
const next = index + 1; const next = index + 1;
// Keep track of the currently checked button
this.checked = buttons.find((button) => button.value === this.value);
for (const button of buttons) { for (const button of buttons) {
button.classList.remove('segment-button-after-checked'); button.classList.remove('segment-button-after-checked');
} }
@ -474,8 +474,6 @@ export class Segment implements ComponentInterface {
this.setCheckedClasses(); this.setCheckedClasses();
} }
} }
this.checked = current;
}; };
private getSegmentButton = (selector: 'first' | 'last' | 'next' | 'previous'): HTMLIonSegmentButtonElement | null => { private getSegmentButton = (selector: 'first' | 'last' | 'next' | 'previous'): HTMLIonSegmentButtonElement | null => {
@ -533,7 +531,7 @@ export class Segment implements ComponentInterface {
if (keyDownSelectsButton) { if (keyDownSelectsButton) {
const previous = this.checked; const previous = this.checked;
this.checkButton(this.checked || current, current); this.checkButton(previous || current, current);
if (current !== previous) { if (current !== previous) {
this.emitValueChange(); this.emitValueChange();
} }

View File

@ -175,4 +175,30 @@ test.describe('segment: events: ionChange', () => {
expect(ionChangeSpy).toHaveReceivedEventTimes(0); expect(ionChangeSpy).toHaveReceivedEventTimes(0);
expect(await segment.evaluate((el: HTMLIonSegmentElement) => el.value)).toBe('2'); expect(await segment.evaluate((el: HTMLIonSegmentElement) => el.value)).toBe('2');
}); });
test('should emit when clicking after changing value programmatically', async ({ page }) => {
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/ionic-team/ionic-framework/issues/27002',
});
await page.setContent(`
<ion-segment value="1" swipe-gesture="false">
<ion-segment-button value="1">One</ion-segment-button>
<ion-segment-button value="2">Two</ion-segment-button>
<ion-segment-button value="3">Three</ion-segment-button>
</ion-segment>
`);
const segment = page.locator('ion-segment');
const segmentButtons = segment.locator('ion-segment-button');
const ionChangeSpy = await page.spyOnEvent('ionChange');
await segment.evaluate((el: HTMLIonSegmentElement) => (el.value = '2'));
await segmentButtons.nth(0).click();
await ionChangeSpy.next();
expect(ionChangeSpy).toHaveReceivedEventDetail({ value: '1' });
});
}); });