@thoughtspot/visual-embed-sdk 1.52.2-beta → 1.52.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/cjs/package.json +2 -2
  2. package/cjs/src/embed/app.js +1 -1
  3. package/cjs/src/embed/app.js.map +1 -1
  4. package/cjs/src/embed/auto-frame-renderer.js +1 -1
  5. package/cjs/src/embed/auto-frame-renderer.js.map +1 -1
  6. package/cjs/src/embed/bodyless-conversation.js +1 -1
  7. package/cjs/src/embed/bodyless-conversation.js.map +1 -1
  8. package/cjs/src/embed/conversation.js +1 -1
  9. package/cjs/src/embed/conversation.js.map +1 -1
  10. package/cjs/src/embed/liveboard.d.ts +1 -0
  11. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  12. package/cjs/src/embed/liveboard.js +16 -4
  13. package/cjs/src/embed/liveboard.js.map +1 -1
  14. package/cjs/src/embed/liveboard.spec.js +54 -0
  15. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  16. package/cjs/src/embed/search-bar.js +1 -1
  17. package/cjs/src/embed/search-bar.js.map +1 -1
  18. package/cjs/src/embed/search.js +1 -1
  19. package/cjs/src/embed/search.js.map +1 -1
  20. package/cjs/src/embed/search.spec.js +0 -20
  21. package/cjs/src/embed/search.spec.js.map +1 -1
  22. package/cjs/src/embed/ts-embed.d.ts +34 -12
  23. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  24. package/cjs/src/embed/ts-embed.js +98 -142
  25. package/cjs/src/embed/ts-embed.js.map +1 -1
  26. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  27. package/cjs/src/embed/ts-embed.spec.js +171 -138
  28. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  29. package/dist/{index-CcBYlGo9.js → index-Bt56pC82.js} +1 -1
  30. package/dist/src/embed/liveboard.d.ts +1 -0
  31. package/dist/src/embed/liveboard.d.ts.map +1 -1
  32. package/dist/src/embed/ts-embed.d.ts +34 -12
  33. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  34. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  35. package/dist/tsembed-react.es.js +161 -155
  36. package/dist/tsembed-react.js +160 -154
  37. package/dist/tsembed.es.js +162 -156
  38. package/dist/tsembed.js +161 -155
  39. package/dist/visual-embed-sdk-react-full.d.ts +35 -12
  40. package/dist/visual-embed-sdk-react.d.ts +35 -12
  41. package/dist/visual-embed-sdk.d.ts +35 -12
  42. package/lib/package.json +2 -2
  43. package/lib/src/embed/app.js +1 -1
  44. package/lib/src/embed/app.js.map +1 -1
  45. package/lib/src/embed/auto-frame-renderer.js +1 -1
  46. package/lib/src/embed/auto-frame-renderer.js.map +1 -1
  47. package/lib/src/embed/bodyless-conversation.js +1 -1
  48. package/lib/src/embed/bodyless-conversation.js.map +1 -1
  49. package/lib/src/embed/conversation.js +1 -1
  50. package/lib/src/embed/conversation.js.map +1 -1
  51. package/lib/src/embed/liveboard.d.ts +1 -0
  52. package/lib/src/embed/liveboard.d.ts.map +1 -1
  53. package/lib/src/embed/liveboard.js +15 -4
  54. package/lib/src/embed/liveboard.js.map +1 -1
  55. package/lib/src/embed/liveboard.spec.js +54 -0
  56. package/lib/src/embed/liveboard.spec.js.map +1 -1
  57. package/lib/src/embed/search-bar.js +1 -1
  58. package/lib/src/embed/search-bar.js.map +1 -1
  59. package/lib/src/embed/search.js +1 -1
  60. package/lib/src/embed/search.js.map +1 -1
  61. package/lib/src/embed/search.spec.js +0 -20
  62. package/lib/src/embed/search.spec.js.map +1 -1
  63. package/lib/src/embed/ts-embed.d.ts +34 -12
  64. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  65. package/lib/src/embed/ts-embed.js +99 -143
  66. package/lib/src/embed/ts-embed.js.map +1 -1
  67. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  68. package/lib/src/embed/ts-embed.spec.js +172 -139
  69. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  70. package/lib/src/visual-embed-sdk.d.ts +35 -12
  71. package/package.json +2 -2
  72. package/src/embed/app.ts +1 -1
  73. package/src/embed/auto-frame-renderer.ts +1 -1
  74. package/src/embed/bodyless-conversation.ts +1 -1
  75. package/src/embed/conversation.ts +1 -1
  76. package/src/embed/liveboard.spec.ts +62 -0
  77. package/src/embed/liveboard.ts +18 -4
  78. package/src/embed/search-bar.tsx +1 -1
  79. package/src/embed/search.spec.ts +0 -23
  80. package/src/embed/search.ts +1 -1
  81. package/src/embed/ts-embed.spec.ts +213 -179
  82. package/src/embed/ts-embed.ts +96 -149
@@ -45,6 +45,7 @@ import {
45
45
  getHostEventsConfig,
46
46
  getValueFromWindow,
47
47
  deserializeParam,
48
+ getScrollableAncestors,
48
49
  } from '../utils';
49
50
  import { getCustomActions } from '../utils/custom-actions';
50
51
  import {
@@ -115,6 +116,9 @@ const TS_EMBED_ID = '_thoughtspot-embed';
115
116
  */
116
117
  const PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY = 'tsEmbedOriginalPosition';
117
118
  const PRERENDER_WRAPPER_ID_PREFIX = 'tsEmbed-pre-render-wrapper-';
119
+ const PRERENDER_PARKED_TRANSFORM = 'translateY(-100%)';
120
+ /** The height createPreRenderWrapper() seeds before anything is measured. */
121
+ const UNMEASURED_WRAPPER_HEIGHT = '100vh';
118
122
 
119
123
  // The container applies UpdateEmbedParams through React state, so a delivered
120
124
  // post is not the same as the params being in effect.
@@ -125,57 +129,6 @@ const UPDATE_EMBED_PARAMS_SETTLE_MS = 200;
125
129
  // truthy and parses to {}.
126
130
  const NO_RUNTIME_PARAMS = '&';
127
131
 
128
- /**
129
- * Query parameters that stay on the iframe `src` while config is excluded from
130
- * the URL, which is the default unless the embed sets the
131
- * `excludeConfigFromURL` additional flag to `false`. These are the parameters the
132
- * application shell needs before it can receive a postMessage at all: the
133
- * embed marker, the host application URL used to validate the message origin,
134
- * the SDK version, the flags that pick the authentication flow, and the
135
- * boot-time settings that would otherwise be applied a frame late (viewport,
136
- * log level, locale, formatting and org). Everything else is delivered over
137
- * `HostEvent.UpdateEmbedParams`.
138
- * @internal
139
- */
140
- const BOOTSTRAP_URL_PARAMS: ReadonlySet<string> = new Set<string>([
141
- Param.EmbedApp,
142
- Param.HostAppUrl,
143
- Param.Version,
144
- Param.AuthType,
145
- Param.AutoLogin,
146
- Param.DisableLoginRedirect,
147
- Param.ForceSAMLAutoRedirect,
148
- Param.cookieless,
149
- Param.preAuthCache,
150
- Param.blockNonEmbedFullAppAccess,
151
- Param.OverrideOrgId,
152
- Param.ViewPortHeight,
153
- Param.ViewPortWidth,
154
- Param.ClientLogLevel,
155
- Param.OverrideNativeConsole,
156
- Param.PendoTrackingKey,
157
- Param.NumberFormatLocale,
158
- Param.DateFormatLocale,
159
- Param.CurrencyFormat,
160
- Param.Locale,
161
- Param.searchEmbed,
162
- Param.livedBoardEmbed,
163
- Param.isSpotterAgentEmbed,
164
- Param.SpotterEnabled,
165
- Param.IsFullAppEmbed,
166
- Param.IsOnBeforeGetVizDataInterceptEnabled,
167
- Param.LinkOverride,
168
- Param.EnableLinkOverridesV2,
169
- Param.DisableRedirectionLinksInNewTab,
170
- Param.OverrideHistoryState,
171
- Param.ForceTable,
172
- Param.StringIDsUrl,
173
- Param.DataSources,
174
- Param.ExposeTranslationIDs,
175
- Param.IconSpriteUrl,
176
- Param.Tag,
177
- ]);
178
-
179
132
  /**
180
133
  * The event id map from v2 event names to v1 event id
181
134
  * v1 events are the classic embed events implemented in Blink v1
@@ -281,8 +234,7 @@ export class TsEmbed {
281
234
 
282
235
  private preRenderContainerEl: HTMLElement = document.body;
283
236
 
284
- private containerScrollListener: (() => void) | null = null;
285
-
237
+ /** Last height the embedded app reported, once fullHeight has measured one. */
286
238
  protected hostEventClient: HostEventClient;
287
239
 
288
240
  protected isReadyForRenderPromise;
@@ -1001,7 +953,7 @@ export class TsEmbed {
1001
953
  }
1002
954
 
1003
955
  protected getEmbedParams() {
1004
- const queryParams = this.getUrlQueryParamsObject();
956
+ const queryParams = this.getEmbedParamsObject();
1005
957
  return getQueryParamString(queryParams);
1006
958
  }
1007
959
 
@@ -1010,16 +962,6 @@ export class TsEmbed {
1010
962
  return params;
1011
963
  }
1012
964
 
1013
- protected getUrlQueryParamsObject(): Record<any, any> {
1014
- const queryParams = this.getEmbedParamsObject();
1015
- if (!this.isConfigExcludedFromUrl()) {
1016
- return queryParams;
1017
- }
1018
- return Object.fromEntries(
1019
- Object.entries(queryParams).filter(([key]) => BOOTSTRAP_URL_PARAMS.has(key)),
1020
- );
1021
- }
1022
-
1023
965
  protected getRootIframeSrc() {
1024
966
  const query = this.getEmbedParams();
1025
967
  return this.getEmbedBasePath(query);
@@ -1208,7 +1150,7 @@ export class TsEmbed {
1208
1150
  top: '0',
1209
1151
  left: '0',
1210
1152
  width: '100vw',
1211
- height: '100vh',
1153
+ height: UNMEASURED_WRAPPER_HEIGHT,
1212
1154
  };
1213
1155
  setStyleProperties(preRenderWrapper, initialPreRenderWrapperStyle);
1214
1156
 
@@ -1294,10 +1236,26 @@ export class TsEmbed {
1294
1236
  }
1295
1237
 
1296
1238
  /**
1297
- * Resolves the configured preRenderContainer to a live element, falling
1298
- * back to `document.body`. A string selector is re-queried on every call so
1299
- * a remounted container (E.g.: React replacing the node) resolves to the
1300
- * fresh element; an element passed directly cannot be re-resolved.
1239
+ * Resolves the configured preRenderContainer to a live element. A string
1240
+ * selector is re-queried on every call so a remounted container (E.g.: React
1241
+ * replacing the node) resolves to the fresh element; an element passed
1242
+ * directly cannot be re-resolved.
1243
+ *
1244
+ * With nothing configured the frame goes into the host element's nearest
1245
+ * scrolling ancestor, falling back to `document.body`.
1246
+ *
1247
+ * The wrapper is absolutely positioned, so it follows the page for free —
1248
+ * but only while it sits inside whatever scrolls. `document.body` is right
1249
+ * only when the document itself is the scroller; an app that scrolls an
1250
+ * inner element instead left the frame pinned to the viewport while the page
1251
+ * moved under it (SCAL-338563). Being inside the scroller also lets wheel
1252
+ * events chain out of the frame into it, which they cannot do from
1253
+ * `document.body`.
1254
+ *
1255
+ * A scrolling ancestor is layout chrome rather than route content, so it
1256
+ * outlives the embed in practice; and if it does go, the host element goes
1257
+ * with it and this instance is remounting anyway.
1258
+ * `reconcilePreRenderContainer` re-runs this on a detached container.
1301
1259
  */
1302
1260
  private resolvePreRenderContainerTarget(): HTMLElement {
1303
1261
  const containerConfig = this.getPreRenderConfig().containerSelector;
@@ -1314,7 +1272,13 @@ export class TsEmbed {
1314
1272
  } else if (containerConfig) {
1315
1273
  container = containerConfig;
1316
1274
  }
1317
- return (container as HTMLElement) ?? document.body;
1275
+ if (container) {
1276
+ return container as HTMLElement;
1277
+ }
1278
+ if (!this.hostElement) {
1279
+ return document.body;
1280
+ }
1281
+ return getScrollableAncestors(this.hostElement)[0] ?? document.body;
1318
1282
  }
1319
1283
 
1320
1284
  private inheritPreRenderContainer(): void {
@@ -1368,8 +1332,9 @@ export class TsEmbed {
1368
1332
  * Re-attaches the wrapper to a live container when the previously resolved
1369
1333
  * one has been detached or no longer holds the wrapper — e.g. the host app
1370
1334
  * remounted a custom preRenderContainer, which would otherwise leave a stale
1371
- * reference and collapse the wrapper. Only string selectors can be
1372
- * re-resolved; a container passed as an element is left untouched.
1335
+ * reference and collapse the wrapper. Selectors and the auto-resolved
1336
+ * scrolling ancestor are both re-resolved; a container passed as an element
1337
+ * is left untouched, as there is nothing to re-query.
1373
1338
  */
1374
1339
  private reconcilePreRenderContainer(): void {
1375
1340
  const wrapper = this.preRenderWrapper;
@@ -1388,14 +1353,6 @@ export class TsEmbed {
1388
1353
  if (resolved === stored && stored.contains(wrapper)) {
1389
1354
  return;
1390
1355
  }
1391
- if (this.containerScrollListener && stored !== resolved) {
1392
- if (stored !== document.body) {
1393
- stored.removeEventListener('scroll', this.containerScrollListener);
1394
- }
1395
- if (resolved !== document.body) {
1396
- resolved.addEventListener('scroll', this.containerScrollListener);
1397
- }
1398
- }
1399
1356
  this.preRenderContainerEl = resolved;
1400
1357
  this.applyPreRenderContainerPositioning();
1401
1358
  if (wrapper.parentNode !== resolved) {
@@ -1464,10 +1421,11 @@ export class TsEmbed {
1464
1421
  */
1465
1422
  protected setIFrameHeight(height: number | string): void {
1466
1423
  if (this.isPreRendered) {
1424
+ const next = getCssDimension(height);
1467
1425
  if (this.insertedDomEl) {
1468
- (this.insertedDomEl as HTMLElement).style.height = getCssDimension(height);
1426
+ (this.insertedDomEl as HTMLElement).style.height = next;
1469
1427
  } else if (this.preRenderWrapper) {
1470
- this.preRenderWrapper.style.height = getCssDimension(height);
1428
+ this.preRenderWrapper.style.height = next;
1471
1429
  }
1472
1430
  } else {
1473
1431
  // normal (non-preRender) mode: size the iframe directly
@@ -1741,9 +1699,6 @@ export class TsEmbed {
1741
1699
  setTimeout(processEmbedContainerReady, AUTH_INIT_FALLBACK_DELAY);
1742
1700
  } else if (source === EmbedEvent.EmbedListenerReady) {
1743
1701
  processEmbedContainerReady();
1744
- if (this.isConfigExcludedFromUrl()) {
1745
- this.triggerUpdateEmbedParams();
1746
- }
1747
1702
  }
1748
1703
  };
1749
1704
 
@@ -2035,15 +1990,27 @@ export class TsEmbed {
2035
1990
  }
2036
1991
 
2037
1992
  /**
2038
- * Detaches and clears the container scroll listener, if one is attached.
2039
- */
2040
- private removeContainerScrollListener(): void {
2041
- if (!this.containerScrollListener) {
1993
+ * Re-sizes the wrapper when its placeholder changes size.
1994
+ *
1995
+ * Position deliberately has no equivalent. An absolutely positioned wrapper
1996
+ * follows its containing block for free, so a correctly placed frame is the
1997
+ * browser's job and costs nothing; repositioning it on scroll would mean a
1998
+ * layout read and a style write per frame to compensate for placing it in
1999
+ * the wrong box. Size is the one thing the browser will not do for us: the
2000
+ * placeholder grows when the embedded app reports a new height, and the
2001
+ * wrapper has to be told.
2002
+ */
2003
+ private observePreRenderSize(): void {
2004
+ if (this.getPreRenderConfig().doNotTrackSize || typeof ResizeObserver === 'undefined') {
2005
+ return;
2006
+ }
2007
+ const placeholder = this.getPreRenderPlaceHolderElement();
2008
+ if (!placeholder) {
2042
2009
  return;
2043
2010
  }
2044
- const customContainer = this.getCustomPreRenderContainer();
2045
- customContainer?.removeEventListener('scroll', this.containerScrollListener);
2046
- this.containerScrollListener = null;
2011
+ this.resizeObserver?.disconnect();
2012
+ this.resizeObserver = new ResizeObserver(() => this.syncPreRenderStyle());
2013
+ this.resizeObserver.observe(placeholder);
2047
2014
  }
2048
2015
 
2049
2016
  /**
@@ -2053,7 +2020,7 @@ export class TsEmbed {
2053
2020
  public destroy(): void {
2054
2021
  try {
2055
2022
  this.removeFullscreenChangeHandler();
2056
- this.removeContainerScrollListener();
2023
+ this.resizeObserver?.disconnect();
2057
2024
  this.unsubscribeToEvents();
2058
2025
  this.preRenderWrapper?.remove();
2059
2026
  this.restorePreRenderContainerPosition();
@@ -2112,29 +2079,6 @@ export class TsEmbed {
2112
2079
  // blocked.
2113
2080
  protected preRenderParamsApplied: Promise<void> = Promise.resolve();
2114
2081
 
2115
- protected isConfigExcludedFromUrl(): boolean {
2116
- const flag =
2117
- this.viewConfig.additionalFlags?.excludeConfigFromURL ??
2118
- this.embedConfig.additionalFlags?.excludeConfigFromURL;
2119
- // Enabled by default; only an explicit false opts out.
2120
- return flag !== false && flag !== 'false';
2121
- }
2122
-
2123
- protected async triggerUpdateEmbedParams(): Promise<void> {
2124
- try {
2125
- const params = await this.getUpdateEmbedParamsObject();
2126
- this.trigger(HostEvent.UpdateEmbedParams, params);
2127
- } catch (error) {
2128
- logger.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
2129
- this.handleError({
2130
- errorType: ErrorDetailsTypes.API,
2131
- message: error?.message || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
2132
- code: EmbedErrorCodes.UPDATE_PARAMS_FAILED,
2133
- error: error?.message || error,
2134
- });
2135
- }
2136
- }
2137
-
2138
2082
  protected beforePrerenderVisible(): void {
2139
2083
  // We can ignore this as its a bit expensive and the newer customers
2140
2084
  // have moved on to UpdateEmbedParams supported clusters
@@ -2145,7 +2089,16 @@ export class TsEmbed {
2145
2089
  this.preRenderParamsApplied = new Promise<void>((resolve) => {
2146
2090
  this.executeAfterEmbedContainerLoaded(async () => {
2147
2091
  try {
2148
- await this.triggerUpdateEmbedParams();
2092
+ const params = await this.getUpdateEmbedParamsObject();
2093
+ this.trigger(HostEvent.UpdateEmbedParams, params);
2094
+ } catch (error) {
2095
+ logger.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
2096
+ this.handleError({
2097
+ errorType: ErrorDetailsTypes.API,
2098
+ message: error?.message || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
2099
+ code: EmbedErrorCodes.UPDATE_PARAMS_FAILED,
2100
+ error: error?.message || error,
2101
+ });
2149
2102
  } finally {
2150
2103
  setTimeout(resolve, UPDATE_EMBED_PARAMS_SETTLE_MS);
2151
2104
  }
@@ -2181,14 +2134,18 @@ export class TsEmbed {
2181
2134
 
2182
2135
  if (this.hostElement) {
2183
2136
  this.insertedDomEl = this.createPreRenderPlaceholder();
2184
- if ((this.viewConfig as { fullHeight: boolean }).fullHeight) {
2185
- // If fullHeight has already sized the wrapper, seed the
2186
- // placeholder with the same height so syncPreRenderStyle gets
2187
- // an accurate rect.
2188
- const existingHeight = this.preRenderWrapper.style.height;
2189
- if (existingHeight) {
2190
- (this.insertedDomEl as HTMLDivElement).style.height = existingHeight;
2191
- }
2137
+ // Carry a height fullHeight has already measured onto the fresh
2138
+ // placeholder, so a re-show does not flash at frameParams height.
2139
+ // UNMEASURED_WRAPPER_HEIGHT is what createPreRenderWrapper() seeds
2140
+ // before anything has been measured; treating that as a measurement
2141
+ // is what made a first reveal overshoot to a full viewport.
2142
+ const wrapperHeight = this.preRenderWrapper.style.height;
2143
+ if (
2144
+ (this.viewConfig as { fullHeight: boolean }).fullHeight
2145
+ && wrapperHeight
2146
+ && wrapperHeight !== UNMEASURED_WRAPPER_HEIGHT
2147
+ ) {
2148
+ (this.insertedDomEl as HTMLDivElement).style.height = wrapperHeight;
2192
2149
  }
2193
2150
 
2194
2151
  const placeHolderId = this.getPreRenderIds().placeHolder;
@@ -2205,32 +2162,20 @@ export class TsEmbed {
2205
2162
  this.hostElement.appendChild(this.insertedDomEl);
2206
2163
 
2207
2164
  this.syncPreRenderStyle();
2208
-
2209
- const customContainer = this.getCustomPreRenderContainer();
2210
- if (customContainer && !this.containerScrollListener) {
2211
- this.containerScrollListener = () => this.syncPreRenderStyle();
2212
- customContainer.addEventListener('scroll', this.containerScrollListener);
2213
- }
2214
-
2215
- if (!this.getPreRenderConfig().doNotTrackSize) {
2216
- const observeTarget = (this.insertedDomEl as HTMLElement) ?? this.hostElement;
2217
- this.resizeObserver = new ResizeObserver((entries) => {
2218
- entries.forEach((entry) => {
2219
- if (entry.target === observeTarget) {
2220
- this.syncPreRenderStyle();
2221
- }
2222
- });
2223
- });
2224
- this.resizeObserver.observe(observeTarget);
2225
- }
2165
+ this.observePreRenderSize();
2226
2166
  }
2227
2167
 
2228
2168
  removeStyleProperties(this.preRenderWrapper, [
2229
2169
  'z-index',
2230
2170
  'opacity',
2231
- 'pointer-events',
2232
2171
  'overflow',
2172
+ 'transform',
2233
2173
  ]);
2174
+ // Set rather than removed: a container that carries `pointer-events:
2175
+ // none` — the usual styling for a parking root that must not swallow
2176
+ // clicks — passes it down, and dropping the property here would leave
2177
+ // the inherited `none` in force and the frame dead to input.
2178
+ setStyleProperties(this.preRenderWrapper, { pointerEvents: 'auto' });
2234
2179
  this.subscribeToEvents();
2235
2180
 
2236
2181
  // Setup fullscreen change handler for prerendered components
@@ -2310,14 +2255,16 @@ export class TsEmbed {
2310
2255
  top: '0',
2311
2256
  left: '0',
2312
2257
  overflow: 'hidden',
2258
+ // Keeps the measured size — so the next show needs no resize, which
2259
+ // is the point of pre-rendering — while lifting the box out of
2260
+ // the container's scrollable area. Overflow only extends
2261
+ // downwards, so a hidden frame parked above the top edge adds
2262
+ // none, where one left at full height shows as blank scroll space.
2263
+ transform: PRERENDER_PARKED_TRANSFORM,
2313
2264
  };
2314
2265
  setStyleProperties(this.preRenderWrapper, preRenderHideStyles);
2315
2266
 
2316
- this.removeContainerScrollListener();
2317
-
2318
- if (this.resizeObserver) {
2319
- this.resizeObserver.disconnect();
2320
- }
2267
+ this.resizeObserver?.disconnect();
2321
2268
 
2322
2269
  const placeHolderEle = this.getPreRenderPlaceHolderElement();
2323
2270
  if (placeHolderEle) {