@truenas/ui-components 0.3.15 → 0.3.16

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.
@@ -8865,7 +8865,6 @@ class TnSelectComponent {
8865
8865
  }
8866
8866
  onChange = (_value) => { };
8867
8867
  onTouched = () => { };
8868
- elementRef = inject(ElementRef);
8869
8868
  cdr = inject(ChangeDetectorRef);
8870
8869
  overlay = inject(Overlay);
8871
8870
  viewContainerRef = inject(ViewContainerRef);
@@ -8937,11 +8936,19 @@ class TnSelectComponent {
8937
8936
  *
8938
8937
  * Why an overlay (vs. an inline absolutely-positioned panel):
8939
8938
  * - Escapes parent `overflow: hidden`/clipping in surrounding layouts.
8940
- * - `outsidePointerEvents()` notifies on outside pointerdown WITHOUT
8941
- * intercepting the click (no backdrop) — so the user's click reaches
8942
- * the underlying target while the select closes silently.
8943
8939
  * - Position is recomputed on scroll so the panel stays attached.
8944
- * - Width is matched to the trigger so the panel doesn't jump in size.
8940
+ *
8941
+ * Dismissal uses a transparent, full-viewport backdrop (`backdropClick()`).
8942
+ * We previously ran backdrop-less with `outsidePointerEvents()`, but that
8943
+ * only closes when the click lands strictly OUTSIDE the overlay pane — and
8944
+ * the pane was sized to the (often full-width) trigger while the panel itself
8945
+ * is only as wide as its content. The empty pane area to the right of the
8946
+ * options stayed `pointer-events: auto`, so clicks there never counted as
8947
+ * "outside" and the dropdown wouldn't close. A transparent backdrop closes on
8948
+ * ANY click outside the panel regardless of pane geometry — the standard
8949
+ * pattern used by native `<select>` and Material's `mat-select`. We therefore
8950
+ * also drop the explicit `width`: the pane sizes to the panel content so the
8951
+ * clickable surface matches what the user sees.
8945
8952
  */
8946
8953
  attachOverlay() {
8947
8954
  const trigger = this.triggerEl().nativeElement;
@@ -8955,25 +8962,17 @@ class TnSelectComponent {
8955
8962
  this.overlayRef = this.overlay.create({
8956
8963
  positionStrategy,
8957
8964
  scrollStrategy: this.overlay.scrollStrategies.reposition(),
8958
- hasBackdrop: false,
8959
- width: trigger.offsetWidth,
8965
+ hasBackdrop: true,
8966
+ backdropClass: 'cdk-overlay-transparent-backdrop',
8960
8967
  });
8961
8968
  const portal = new TemplatePortal(this.dropdownTemplate(), this.viewContainerRef);
8962
8969
  this.overlayRef.attach(portal);
8963
- // Click-outside (non-intercepting). The pointer event still reaches the
8964
- // element the user clicked; we just notice and close.
8965
- //
8966
- // Important: ignore events whose target is inside the select host. A
8967
- // pointerdown on the trigger is "outside the overlay" from CDK's POV but
8968
- // it's our own toggle target — letting closeDropdown fire here races the
8969
- // trigger's click handler and the dropdown immediately reopens.
8970
- this.overlaySubs.push(this.overlayRef.outsidePointerEvents().subscribe((event) => {
8971
- const target = event.target;
8972
- if (target && this.elementRef.nativeElement.contains(target)) {
8973
- return;
8974
- }
8975
- this.closeDropdown(false);
8976
- }));
8970
+ // Dismiss on any click outside the panel. The transparent backdrop spans
8971
+ // the viewport and captures the click, so this fires no matter where the
8972
+ // user clicks (including the empty area beside a narrow panel). Clicking
8973
+ // the trigger while open also hits the backdrop it closes here and the
8974
+ // trigger's own click never fires, so there's no reopen race.
8975
+ this.overlaySubs.push(this.overlayRef.backdropClick().subscribe(() => this.closeDropdown(false)));
8977
8976
  // Escape as a fallback (the trigger keydown handler covers the common case,
8978
8977
  // but if focus ever moves into the panel, this catches it too).
8979
8978
  this.overlaySubs.push(this.overlayRef.keydownEvents().subscribe((event) => {