@ascentgl/ads-ui 21.112.0 → 21.114.0

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.
@@ -6302,6 +6302,8 @@ class AdsDatepickerComponent extends AdsDatetimepickerComponent {
6302
6302
  this.inputModifiedByKeyHandler = false;
6303
6303
  /** @ignore */
6304
6304
  this.elementRef = inject(ElementRef);
6305
+ /** @ignore */
6306
+ this.overlayContainerRef = inject(OverlayContainer);
6305
6307
  }
6306
6308
  /** @ignore */
6307
6309
  ngOnInit() {
@@ -6314,6 +6316,8 @@ class AdsDatepickerComponent extends AdsDatetimepickerComponent {
6314
6316
  ngOnDestroy() {
6315
6317
  super.ngOnDestroy();
6316
6318
  this.intersectionObserver?.disconnect();
6319
+ this.scrollPassthroughCleanup?.();
6320
+ this.scrollPassthroughCleanup = undefined;
6317
6321
  }
6318
6322
  /** @ignore */
6319
6323
  setupIntersectionObserver() {
@@ -6330,6 +6334,85 @@ class AdsDatepickerComponent extends AdsDatetimepickerComponent {
6330
6334
  });
6331
6335
  this.intersectionObserver.observe(this.elementRef.nativeElement);
6332
6336
  }
6337
+ /**
6338
+ * @ignore
6339
+ * The CDK overlay backdrop has `pointer-events: auto` which intercepts all
6340
+ * pointer / wheel events, preventing native scroll on underlying containers.
6341
+ * Disabling pointer events on the backdrop lets the browser handle scrolling
6342
+ * natively (preserving momentum / inertia). A document-level pointerdown
6343
+ * listener replaces the lost backdrop click-to-close behaviour.
6344
+ */
6345
+ onOpened() {
6346
+ super.onOpened();
6347
+ this.setupScrollPassthrough();
6348
+ }
6349
+ /** @ignore */
6350
+ onClosed() {
6351
+ this.scrollPassthroughCleanup?.();
6352
+ this.scrollPassthroughCleanup = undefined;
6353
+ super.onClosed();
6354
+ }
6355
+ /** @ignore */
6356
+ setupScrollPassthrough() {
6357
+ this.scrollPassthroughCleanup?.();
6358
+ this.scrollPassthroughCleanup = undefined;
6359
+ const container = this.overlayContainerRef.getContainerElement();
6360
+ const backdrop = container.querySelector('.cdk-overlay-backdrop');
6361
+ // Disable pointer events on the backdrop so that wheel / touch events
6362
+ // reach the scroll container natively. This preserves momentum scrolling
6363
+ // and avoids the scroll-stop when closeOnOutOfView closes the picker mid-scroll.
6364
+ if (backdrop) {
6365
+ backdrop.style.pointerEvents = 'none';
6366
+ }
6367
+ const cleanupFns = [];
6368
+ // Replace the backdrop click-to-close with a document-level pointerdown
6369
+ // listener. Delay one animation frame so the interaction that opened the
6370
+ // picker does not immediately close it.
6371
+ let pointerDownCleanup;
6372
+ const rafId = requestAnimationFrame(() => {
6373
+ const onPointerDown = (event) => {
6374
+ if (!this.picker?.opened)
6375
+ return;
6376
+ const overlayPane = container.querySelector('.cdk-overlay-pane');
6377
+ const clickedInside = overlayPane?.contains(event.target) ||
6378
+ this.elementRef.nativeElement.contains(event.target);
6379
+ if (!clickedInside) {
6380
+ this.picker.close();
6381
+ }
6382
+ };
6383
+ document.addEventListener('pointerdown', onPointerDown);
6384
+ pointerDownCleanup = () => document.removeEventListener('pointerdown', onPointerDown);
6385
+ });
6386
+ cleanupFns.push(() => {
6387
+ cancelAnimationFrame(rafId);
6388
+ pointerDownCleanup?.();
6389
+ });
6390
+ // Reposition the calendar overlay when a non-document scroll container scrolls.
6391
+ // CDK ScrollDispatcher only detects window scroll and CdkScrollable directives,
6392
+ // not arbitrary overflow containers, so we trigger the update manually.
6393
+ const scrollTarget = this.findScrollableAncestor(this.elementRef.nativeElement);
6394
+ if (scrollTarget) {
6395
+ const onScroll = () => {
6396
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6397
+ this.picker?._popupRef?.updatePosition();
6398
+ };
6399
+ scrollTarget.addEventListener('scroll', onScroll, { passive: true });
6400
+ cleanupFns.push(() => scrollTarget.removeEventListener('scroll', onScroll));
6401
+ }
6402
+ this.scrollPassthroughCleanup = () => cleanupFns.forEach((fn) => fn());
6403
+ }
6404
+ /** @ignore - Walk up the DOM to find the first ancestor with overflow-y: auto|scroll */
6405
+ findScrollableAncestor(node) {
6406
+ let current = node.parentElement;
6407
+ while (current) {
6408
+ const { overflowY } = getComputedStyle(current);
6409
+ if (overflowY === 'auto' || overflowY === 'scroll') {
6410
+ return current;
6411
+ }
6412
+ current = current.parentElement;
6413
+ }
6414
+ return null;
6415
+ }
6333
6416
  /** @ignore - Override to dispatch change event on blur when input was modified programmatically */
6334
6417
  touchControls() {
6335
6418
  // Mark controls as touched BEFORE dispatching the change event.