Skip to content

Commit 3c03b9b

Browse files
committed
add intersection fix
1 parent 16cbe63 commit 3c03b9b

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

core/src/components/datetime/datetime.tsx

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ export class Datetime implements ComponentInterface {
124124
private destroyCalendarListener?: () => void;
125125
private destroyKeyboardMO?: () => void;
126126

127+
/**
128+
* Tracks the current visibility state of the datetime component.
129+
* This prevents race conditions when the datetime rapidly becomes visible/hidden
130+
* (e.g., when dragging a modal on iOS), ensuring the datetime-ready class
131+
* accurately reflects the component's current intersection state.
132+
*/
133+
private isIntersecting = false;
134+
127135
// TODO(FW-2832): types (DatetimeParts causes some errors that need untangling)
128136
private minParts?: any;
129137
private maxParts?: any;
@@ -1148,6 +1156,13 @@ export class Datetime implements ComponentInterface {
11481156
return;
11491157
}
11501158

1159+
/**
1160+
* Track that the component is now intersecting.
1161+
* This prevents stale writeTask operations from incorrectly
1162+
* removing the datetime-ready class.
1163+
*/
1164+
this.isIntersecting = true;
1165+
11511166
this.initializeListeners();
11521167

11531168
/**
@@ -1159,7 +1174,14 @@ export class Datetime implements ComponentInterface {
11591174
* is a better way to handle this?
11601175
*/
11611176
writeTask(() => {
1162-
this.el.classList.add('datetime-ready');
1177+
/**
1178+
* Only add the class if the component is still intersecting.
1179+
* This prevents race conditions when the visibility state changes
1180+
* rapidly (e.g., when dragging a modal on iOS).
1181+
*/
1182+
if (this.isIntersecting) {
1183+
this.el.classList.add('datetime-ready');
1184+
}
11631185
});
11641186
};
11651187
const visibleIO = new IntersectionObserver(visibleCallback, { threshold: 0.01, root: el });
@@ -1197,6 +1219,13 @@ export class Datetime implements ComponentInterface {
11971219
return;
11981220
}
11991221

1222+
/**
1223+
* Track that the component is no longer intersecting.
1224+
* This prevents stale writeTask operations from incorrectly
1225+
* adding the datetime-ready class.
1226+
*/
1227+
this.isIntersecting = false;
1228+
12001229
this.destroyInteractionListeners();
12011230

12021231
/**
@@ -1209,7 +1238,14 @@ export class Datetime implements ComponentInterface {
12091238
this.showMonthAndYear = false;
12101239

12111240
writeTask(() => {
1212-
this.el.classList.remove('datetime-ready');
1241+
/**
1242+
* Only remove the class if the component is still not intersecting.
1243+
* This prevents race conditions when the visibility state changes
1244+
* rapidly (e.g., when dragging a modal on iOS).
1245+
*/
1246+
if (!this.isIntersecting) {
1247+
this.el.classList.remove('datetime-ready');
1248+
}
12131249
});
12141250
};
12151251
const hiddenIO = new IntersectionObserver(hiddenCallback, { threshold: 0, root: el });

0 commit comments

Comments
 (0)