@acorex/components 20.7.22 → 20.7.24

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.
@@ -6,7 +6,7 @@ import { AXUnsubscriber, AXHtmlUtil } from '@acorex/core/utils';
6
6
  import { AXZIndexService } from '@acorex/core/z-index';
7
7
  import { isPlatformBrowser, NgTemplateOutlet, AsyncPipe } from '@angular/common';
8
8
  import * as i0 from '@angular/core';
9
- import { Injectable, signal, inject, Renderer2, computed, output, input, afterNextRender, HostBinding, HostListener, ChangeDetectionStrategy, ViewEncapsulation, Component, DOCUMENT, PLATFORM_ID, NgModule } from '@angular/core';
9
+ import { Injectable, signal, inject, Renderer2, computed, output, input, afterNextRender, HostBinding, HostListener, ChangeDetectionStrategy, ViewEncapsulation, Component, DOCUMENT, PLATFORM_ID, Injector, NgModule } from '@angular/core';
10
10
  import { cloneDeep } from 'lodash-es';
11
11
  import { Subject } from 'rxjs';
12
12
 
@@ -440,7 +440,9 @@ class AXContextMenuComponent extends NXComponent {
440
440
  this.document = inject(DOCUMENT);
441
441
  this.platformID = inject(PLATFORM_ID);
442
442
  this.zIndexService = inject(AXZIndexService);
443
+ this.injector = inject(Injector);
443
444
  this.zToken = null;
445
+ this.lastOpenPoint = null;
444
446
  this.originalNextSibling = null;
445
447
  this.originalParent = null;
446
448
  this.items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : []));
@@ -504,6 +506,7 @@ class AXContextMenuComponent extends NXComponent {
504
506
  close() {
505
507
  const wasOpen = this.nativeElement.classList.contains('ax-state-open');
506
508
  this.nativeElement.classList.remove('ax-state-open');
509
+ this.lastOpenPoint = null;
507
510
  this.removeBackdrop();
508
511
  // Release z-index token
509
512
  this.zIndexService.release(this.zToken);
@@ -561,12 +564,27 @@ class AXContextMenuComponent extends NXComponent {
561
564
  }
562
565
  /** @ignore */
563
566
  internalShowAt(point) {
567
+ this.lastOpenPoint = point;
564
568
  const elementRef = this.nativeElement;
565
569
  elementRef.classList.add('ax-state-open');
566
- const itemRect = elementRef.getBoundingClientRect();
570
+ this.positionAtPoint(point);
571
+ this.createBackdrop();
572
+ // Items may render after the signal update (e.g. compact side-menu); reposition once laid out.
573
+ afterNextRender(() => {
574
+ if (this.lastOpenPoint && elementRef.classList.contains('ax-state-open')) {
575
+ this.positionAtPoint(this.lastOpenPoint);
576
+ }
577
+ }, { injector: this.injector });
578
+ }
579
+ /**
580
+ * Positions the menu at `point`, flipping when it would overflow the viewport.
581
+ * Uses a temporary visible layout pass so parents that hide the host (e.g. side-menu `display: none`) do not yield a zero-sized rect.
582
+ */
583
+ positionAtPoint(point) {
584
+ const elementRef = this.nativeElement;
585
+ const itemRect = this.measureMenuRect(elementRef);
567
586
  const windowWidth = window.innerWidth;
568
587
  const windowHeight = window.innerHeight;
569
- // Detect RTL (Right-To-Left) mode
570
588
  const isRtl = AXHtmlUtil.isRtl(elementRef);
571
589
  let left;
572
590
  if (isRtl) {
@@ -595,7 +613,15 @@ class AXContextMenuComponent extends NXComponent {
595
613
  this.renderer.setStyle(elementRef, 'left', `${left}px`);
596
614
  this.renderer.setStyle(elementRef, 'top', `${top}px`);
597
615
  this.renderer.setStyle(elementRef, 'position', 'fixed');
598
- this.createBackdrop();
616
+ }
617
+ /** Measures menu size even when an ancestor hides the host with `display: none`. */
618
+ measureMenuRect(elementRef) {
619
+ this.renderer.setStyle(elementRef, 'visibility', 'hidden');
620
+ this.renderer.setStyle(elementRef, 'display', 'flex');
621
+ const rect = elementRef.getBoundingClientRect();
622
+ this.renderer.removeStyle(elementRef, 'visibility');
623
+ this.renderer.removeStyle(elementRef, 'display');
624
+ return rect;
599
625
  }
600
626
  /** @ignore */
601
627
  createBackdrop() {