@kouji-ui/core 0.6.1 → 0.6.2

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.
@@ -13522,8 +13522,23 @@ function nextConfirmPopupMessageId() {
13522
13522
  * @doc-category Core/Overlay
13523
13523
  */
13524
13524
  class KjConfirmPopup {
13525
- /** The overlay controller provided by the trigger directive on the same element. */
13526
- controller = inject(KjOverlayController, { optional: true });
13525
+ /** The overlay controller, when the trigger sits on this very element. */
13526
+ selfController = inject(KjOverlayController, { optional: true });
13527
+ /**
13528
+ * The controller of a nested `[kjConfirmPopupTrigger]`. The documented
13529
+ * composition puts the trigger on a CHILD of `[kjConfirmPopup]` (see every
13530
+ * example), so the controller is NOT in this element's injector — without
13531
+ * this registration `close()` bailed out and `(kjConfirmed)` never fired.
13532
+ */
13533
+ registered = signal(null, /* @ts-ignore */
13534
+ ...(ngDevMode ? [{ debugName: "registered" }] : /* istanbul ignore next */ []));
13535
+ /** @internal — called by a nested `[kjConfirmPopupTrigger]`. */
13536
+ _registerController(c) {
13537
+ this.registered.set(c);
13538
+ }
13539
+ controllerOf() {
13540
+ return this.selfController ?? this.registered();
13541
+ }
13527
13542
  /** When `true`, the confirm action renders with destructive intent. */
13528
13543
  kjDestructive = input(false, { ...(ngDevMode ? { debugName: "kjDestructive" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
13529
13544
  /** Where to place initial focus. Default `'cancel'`. */
@@ -13537,10 +13552,8 @@ class KjConfirmPopup {
13537
13552
  kjResult = output();
13538
13553
  // ── KjConfirmPopupContext ──────────────────────────────────────────
13539
13554
  /** Open state forwarded from the underlying controller. */
13540
- open = (() => {
13541
- const ctrl = this.controller;
13542
- return ctrl ? ctrl.isOpen : (() => false);
13543
- })();
13555
+ open = computed(() => this.controllerOf()?.isOpen() ?? false, /* @ts-ignore */
13556
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
13544
13557
  /** Whether the confirm action should render destructively. */
13545
13558
  destructive = this.kjDestructive;
13546
13559
  /** Resolved default focus target. */
@@ -13552,7 +13565,7 @@ class KjConfirmPopup {
13552
13565
  constructor() {
13553
13566
  // Bridge the controller's open signal into the resolution contract.
13554
13567
  effect(() => {
13555
- const isOpen = this.controller?.isOpen() ?? false;
13568
+ const isOpen = this.controllerOf()?.isOpen() ?? false;
13556
13569
  if (isOpen && !this.wasOpen) {
13557
13570
  this.resolved = false;
13558
13571
  }
@@ -13568,7 +13581,8 @@ class KjConfirmPopup {
13568
13581
  * Close the popup with the given result. `true` confirms, `false` cancels.
13569
13582
  */
13570
13583
  close(result) {
13571
- if (!this.controller || !this.controller.isOpen())
13584
+ const controller = this.controllerOf();
13585
+ if (!controller || !controller.isOpen())
13572
13586
  return;
13573
13587
  this.resolved = true;
13574
13588
  if (result)
@@ -13576,7 +13590,7 @@ class KjConfirmPopup {
13576
13590
  else
13577
13591
  this.kjCancelled.emit();
13578
13592
  this.kjResult.emit(result);
13579
- this.controller.close('programmatic');
13593
+ controller.close('programmatic');
13580
13594
  }
13581
13595
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjConfirmPopup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
13582
13596
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: KjConfirmPopup, isStandalone: true, selector: "[kjConfirmPopup]", inputs: { kjDestructive: { classPropertyName: "kjDestructive", publicName: "kjDestructive", isSignal: true, isRequired: false, transformFunction: null }, kjDefaultFocus: { classPropertyName: "kjDefaultFocus", publicName: "kjDefaultFocus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { kjConfirmed: "kjConfirmed", kjCancelled: "kjCancelled", kjResult: "kjResult" }, providers: [
@@ -13604,6 +13618,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
13604
13618
  */
13605
13619
  class KjConfirmPopupTrigger {
13606
13620
  _overlayTrigger = inject(KjOverlayTrigger, { self: true });
13621
+ constructor() {
13622
+ // The trigger normally sits on a CHILD of `[kjConfirmPopup]`, so the root
13623
+ // cannot see this controller through its own injector. Hand it over, or
13624
+ // the confirm/cancel slots resolve nothing.
13625
+ inject(KJ_CONFIRM_POPUP, { optional: true })?._registerController?.(this._overlayTrigger.controller);
13626
+ }
13607
13627
  /** Forwarded controller for sibling `[kjFor]` panels. */
13608
13628
  get controller() {
13609
13629
  return this._overlayTrigger.controller;
@@ -13622,7 +13642,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
13622
13642
  exportAs: 'kjConfirmPopupTrigger',
13623
13643
  hostDirectives: [KjPopoverTrigger],
13624
13644
  }]
13625
- }] });
13645
+ }], ctorParameters: () => [] });
13626
13646
 
13627
13647
  /**
13628
13648
  * The floating confirm popup panel. Composes `kj-popover-content` (a
@@ -15576,12 +15596,20 @@ class KjCommandPalette {
15576
15596
  }
15577
15597
  });
15578
15598
  });
15579
- // When items register asynchronously (same query), pick first if nothing highlighted.
15599
+ // Re-seed when the visible set changes under the active item: items may
15600
+ // register asynchronously (nothing highlighted yet), and with
15601
+ // `[kjShouldFilter]="false"` the consumer re-renders the list AFTER the
15602
+ // query effect above ran — so that effect highlighted an item that is
15603
+ // already gone. Without the `some()` check the palette kept a stale value,
15604
+ // no row was active, and Enter did nothing (reproducible by typing fast
15605
+ // or pasting a query).
15580
15606
  effect(() => {
15581
15607
  const visible = this.visibleItems();
15582
15608
  const active = this.kjValue();
15583
15609
  const autoFirst = this.kjAutoActivateFirst();
15584
- if (!autoFirst || visible.length === 0 || active !== null)
15610
+ if (!autoFirst || visible.length === 0)
15611
+ return;
15612
+ if (active !== null && visible.some(i => i.value() === active))
15585
15613
  return;
15586
15614
  untracked(() => {
15587
15615
  const nav = this._nav();