Skip to content

Commit 273081d

Browse files
committed
fix(datetime): moving to overlay listeners for showing instead
1 parent 12ef934 commit 273081d

File tree

1 file changed

+28
-31
lines changed

1 file changed

+28
-31
lines changed

core/src/components/datetime/datetime.tsx

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export class Datetime implements ComponentInterface {
118118

119119
private destroyCalendarListener?: () => void;
120120
private destroyKeyboardMO?: () => void;
121+
private destroyOverlayListeners?: () => void;
121122

122123
// TODO(FW-2832): types (DatetimeParts causes some errors that need untangling)
123124
private minParts?: any;
@@ -1081,6 +1082,10 @@ export class Datetime implements ComponentInterface {
10811082
this.resizeObserver.disconnect();
10821083
this.resizeObserver = undefined;
10831084
}
1085+
if (this.destroyOverlayListeners) {
1086+
this.destroyOverlayListeners();
1087+
this.destroyOverlayListeners = undefined;
1088+
}
10841089
}
10851090

10861091
/**
@@ -1105,26 +1110,6 @@ export class Datetime implements ComponentInterface {
11051110
this.initializeKeyboardListeners();
11061111
}
11071112

1108-
/**
1109-
* FW-6931: Fallback check for when ResizeObserver doesn't fire reliably
1110-
* (e.g., WebKit during modal re-presentation). Called after element is
1111-
* hidden to catch when it becomes visible again.
1112-
*/
1113-
private checkVisibilityFallback = () => {
1114-
const { el } = this;
1115-
if (el.classList.contains('datetime-ready')) {
1116-
return;
1117-
}
1118-
1119-
const rect = el.getBoundingClientRect();
1120-
if (rect.width > 0 && rect.height > 0) {
1121-
this.initializeListeners();
1122-
writeTask(() => {
1123-
el.classList.add('datetime-ready');
1124-
});
1125-
}
1126-
};
1127-
11281113
componentDidLoad() {
11291114
const { el } = this;
11301115

@@ -1141,6 +1126,9 @@ export class Datetime implements ComponentInterface {
11411126
* especially when the element is inside a modal or popover.
11421127
*/
11431128
const markReady = () => {
1129+
if (el.classList.contains('datetime-ready')) {
1130+
return;
1131+
}
11441132
this.initializeListeners();
11451133
writeTask(() => {
11461134
el.classList.add('datetime-ready');
@@ -1153,13 +1141,28 @@ export class Datetime implements ComponentInterface {
11531141
writeTask(() => {
11541142
el.classList.remove('datetime-ready');
11551143
});
1156-
/**
1157-
* Schedule fallback check for browsers where ResizeObserver
1158-
* doesn't fire reliably on re-presentation (e.g., WebKit).
1159-
*/
1160-
setTimeout(() => this.checkVisibilityFallback(), 100);
11611144
};
11621145

1146+
/**
1147+
* FW-6931: If datetime is inside a popover or modal, listen for the
1148+
* overlay's present/dismiss events. This is more reliable than
1149+
* ResizeObserver in some browsers (e.g., WebKit) where the observer
1150+
* doesn't always fire when the overlay opens.
1151+
*/
1152+
const parentOverlay = el.closest('ion-modal, ion-popover') as HTMLIonModalElement | HTMLIonPopoverElement | null;
1153+
if (parentOverlay) {
1154+
const handlePresent = () => markReady();
1155+
const handleDismiss = () => markHidden();
1156+
1157+
parentOverlay.addEventListener('didPresent', handlePresent);
1158+
parentOverlay.addEventListener('didDismiss', handleDismiss);
1159+
1160+
this.destroyOverlayListeners = () => {
1161+
parentOverlay.removeEventListener('didPresent', handlePresent);
1162+
parentOverlay.removeEventListener('didDismiss', handleDismiss);
1163+
};
1164+
}
1165+
11631166
if (typeof ResizeObserver !== 'undefined') {
11641167
this.resizeObserver = new ResizeObserver((entries) => {
11651168
const entry = entries[0];
@@ -1179,12 +1182,6 @@ export class Datetime implements ComponentInterface {
11791182
* its display animation starting (such as when shown in a modal).
11801183
*/
11811184
raf(() => this.resizeObserver?.observe(el));
1182-
1183-
/**
1184-
* Fallback for initial presentation in case ResizeObserver
1185-
* doesn't fire reliably (e.g., WebKit).
1186-
*/
1187-
setTimeout(() => this.checkVisibilityFallback(), 100);
11881185
} else {
11891186
/**
11901187
* Fallback for test environments where ResizeObserver is not available.

0 commit comments

Comments
 (0)