Skip to content

Commit 2909b08

Browse files
authored
fix(datetime): presentation time emits ionChange once (#24968)
Resolves #24967
1 parent a8fd2d9 commit 2909b08

File tree

3 files changed

+72
-11
lines changed

3 files changed

+72
-11
lines changed

core/src/components/datetime/test/presentation/e2e.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { newE2EPage } from '@stencil/core/testing';
1+
import { newE2EPage, E2EPage } from '@stencil/core/testing';
22

33
test('presentation', async () => {
44
const page = await newE2EPage({
@@ -13,3 +13,37 @@ test('presentation', async () => {
1313
expect(screenshotCompare).toMatchScreenshot();
1414
}
1515
});
16+
17+
describe('presentation: time', () => {
18+
19+
let page: E2EPage;
20+
21+
beforeEach(async () => {
22+
page = await newE2EPage({
23+
url: '/src/components/datetime/test/presentation?ionic:_testing=true'
24+
});
25+
});
26+
27+
describe('when the time picker is visible in the view', () => {
28+
29+
it('manually setting the value should emit ionChange once', async () => {
30+
const datetime = await page.find('ion-datetime[presentation="time"]');
31+
const didChange = await datetime.spyOnEvent('ionChange');
32+
33+
await page.$eval('ion-datetime[presentation="time"]', (el: any) => {
34+
el.scrollIntoView();
35+
});
36+
37+
await page.$eval('ion-datetime[presentation="time"]', (el: any) => {
38+
el.value = '06:02:40';
39+
});
40+
41+
await page.waitForChanges();
42+
43+
expect(didChange).toHaveReceivedEventTimes(1);
44+
expect(didChange).toHaveReceivedEventDetail({ value: '06:02:40' });
45+
});
46+
47+
});
48+
49+
});

core/src/components/picker-column-internal/picker-column-internal.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,10 @@ export class PickerColumnInternal implements ComponentInterface {
6767
valueChange() {
6868
if (this.isColumnVisible) {
6969
/**
70-
* Only scroll the active item into view and emit the value
71-
* change, when the picker column is actively visible to the user.
70+
* Only scroll the active item into view when the picker column
71+
* is actively visible to the user.
7272
*/
73-
const { items, value } = this;
7473
this.scrollActiveItemIntoView();
75-
76-
const findItem = items.find(item => item.value === value);
77-
if (findItem) {
78-
this.ionChange.emit(findItem);
79-
}
8074
}
8175
}
8276

@@ -133,7 +127,7 @@ export class PickerColumnInternal implements ComponentInterface {
133127
* first item to match the scroll position of the column.
134128
*
135129
*/
136-
this.value = items[0].value;
130+
this.setValue(items[0].value);
137131
}
138132
}
139133
}
@@ -148,6 +142,15 @@ export class PickerColumnInternal implements ComponentInterface {
148142
}
149143
}
150144

145+
private setValue(value?: string | number) {
146+
const { items } = this;
147+
this.value = value;
148+
const findItem = items.find(item => item.value === value);
149+
if (findItem) {
150+
this.ionChange.emit(findItem);
151+
}
152+
}
153+
151154
private centerPickerItemInView = (target: HTMLElement, smooth = true) => {
152155
const { el, isColumnVisible } = this;
153156
if (isColumnVisible) {
@@ -250,7 +253,7 @@ export class PickerColumnInternal implements ComponentInterface {
250253
const selectedItem = this.items[index];
251254

252255
if (selectedItem.value !== this.value) {
253-
this.value = selectedItem.value;
256+
this.setValue(selectedItem.value);
254257
hapticSelectionEnd();
255258
this.hapticsStarted = false;
256259
}

core/src/components/picker-column-internal/test/basic/e2e.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,30 @@ describe('picker-column-internal', () => {
5151
expect(activeColumn.innerText).toEqual('23');
5252
});
5353

54+
it('should not emit ionChange when the value is modified externally', async () => {
55+
const pickerColumn = await page.find('#default');
56+
const ionChangeSpy = await pickerColumn.spyOnEvent('ionChange');
57+
58+
await page.$eval('#default', (el: any) => {
59+
el.value = '12';
60+
});
61+
62+
expect(ionChangeSpy).not.toHaveReceivedEvent();
63+
});
64+
65+
it('should emit ionChange when the picker is scrolled', async () => {
66+
const pickerColumn = await page.find('#default');
67+
const ionChangeSpy = await pickerColumn.spyOnEvent('ionChange');
68+
69+
await page.$eval('#default', (el: any) => {
70+
el.scrollTo(0, 300);
71+
});
72+
73+
await ionChangeSpy.next();
74+
75+
expect(ionChangeSpy).toHaveReceivedEvent();
76+
});
77+
5478
});
5579

5680
});

0 commit comments

Comments
 (0)