From f6aeb96d7b7de94485922bab45123f8575e0dae2 Mon Sep 17 00:00:00 2001 From: junglerobba Date: Wed, 1 Oct 2025 19:57:48 +0200 Subject: [PATCH] feat(NbDialogService): support passing values to input/model signals This makes an exception for input and model signals in the DialogConfig context, so the typehint will show as the type of the signal's value, but internally it will create a signal with the passed value. Technically these will just be readonly signals instead of input or model signals, but since components used as a dialog do not support regular outputs anyway, it should not matter. When used in a regular context the input signal will not be overwritten and work as usual. closes https://github.com/akveo/nebular/issues/3256 (I would not classify this as a bug but a missing feature instead) --- .../theme/components/dialog/dialog-config.ts | 12 ++++++++++-- .../theme/components/dialog/dialog.service.ts | 13 +++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/framework/theme/components/dialog/dialog-config.ts b/src/framework/theme/components/dialog/dialog-config.ts index dfa6f04f9e..7b819ce0c9 100644 --- a/src/framework/theme/components/dialog/dialog-config.ts +++ b/src/framework/theme/components/dialog/dialog-config.ts @@ -4,11 +4,19 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -import { InjectionToken, ViewContainerRef } from '@angular/core'; +import { InjectionToken, InputSignal, Signal, ViewContainerRef } from '@angular/core'; export const NB_DIALOG_CONFIG = new InjectionToken('Default dialog options'); +type DialogData = { + [K in keyof T]: ExtractInputSignalType; +}; + +type ExtractInputSignalType = Type extends InputSignal ? X : ExcludeSignal; + +type ExcludeSignal = Type extends Signal ? never : Type; + /** * Describes all available options that may be passed to the NbDialogService. * */ @@ -56,7 +64,7 @@ export class NbDialogConfig { */ viewContainerRef: ViewContainerRef; - context: D; + context: DialogData; constructor(config: Partial) { Object.assign(this, config); diff --git a/src/framework/theme/components/dialog/dialog.service.ts b/src/framework/theme/components/dialog/dialog.service.ts index b22a0a52e5..4f03d2b8c4 100644 --- a/src/framework/theme/components/dialog/dialog.service.ts +++ b/src/framework/theme/components/dialog/dialog.service.ts @@ -4,7 +4,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -import { Inject, Injectable, Injector, TemplateRef, Type } from '@angular/core'; +import { Inject, Injectable, Injector, signal, TemplateRef, Type } from '@angular/core'; import { fromEvent as observableFromEvent } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; @@ -20,6 +20,7 @@ import { NB_DOCUMENT } from '../../theme.options'; import { NB_DIALOG_CONFIG, NbDialogConfig } from './dialog-config'; import { NbDialogRef } from './dialog-ref'; import { NbDialogContainerComponent } from './dialog-container'; +import { SIGNAL } from '@angular/core/primitives/signals'; /** @@ -211,7 +212,15 @@ export class NbDialogService { dialogRef.componentRef = container.attachComponentPortal(portal); if (config.context) { - Object.assign(dialogRef.componentRef.instance, { ...config.context }) + for (const [key, value] of Object.entries({...config.context})) { + const instance = dialogRef.componentRef.instance; + const member = instance[key]; + if (typeof member === 'function' && member[SIGNAL] !== undefined) { + instance[key] = signal(value).asReadonly(); + } else { + instance[key] = value; + } + } } } }