From 1c679893709292699104a9a21a2e74a82fe863e3 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 24 Apr 2026 11:01:39 +0200 Subject: [PATCH 1/3] feat(cdk/dialog): add the ability to pass bindings Adds the ability to pass a `Binding[]` to the component being rendered. --- goldens/cdk/dialog/index.api.md | 1 + src/cdk/dialog/dialog-config.ts | 8 +++++++- src/cdk/dialog/dialog.spec.ts | 12 ++++++++++++ src/cdk/dialog/dialog.ts | 8 +++++++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/goldens/cdk/dialog/index.api.md b/goldens/cdk/dialog/index.api.md index 3a84074f0660..2a30553833d1 100644 --- a/goldens/cdk/dialog/index.api.md +++ b/goldens/cdk/dialog/index.api.md @@ -120,6 +120,7 @@ export class DialogConfig | (() => Record); + + /** + * Bindings to apply to the component rendered inside the dialog. + * Does nothing for template-based dialogs. + */ + bindings?: Binding[]; } diff --git a/src/cdk/dialog/dialog.spec.ts b/src/cdk/dialog/dialog.spec.ts index 1884b0e946f6..ddcf52f520da 100644 --- a/src/cdk/dialog/dialog.spec.ts +++ b/src/cdk/dialog/dialog.spec.ts @@ -17,11 +17,13 @@ import { Directive, InjectionToken, Injector, + Input, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation, inject, + inputBinding, } from '@angular/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; @@ -606,6 +608,15 @@ describe('Dialog', () => { expect(dialogRef.componentInstance!.data).toBeNull(); }).not.toThrow(); }); + + it('should be able to apply bindings', () => { + const dialogRef = dialog.open(PizzaMsg, { + bindings: [inputBinding('flavor', () => 'pepperoni')], + }); + viewContainerFixture.detectChanges(); + + expect(dialogRef.componentInstance!.flavor).toBe('pepperoni'); + }); }); it('should not keep a reference to the component after the dialog is closed', () => { @@ -1364,6 +1375,7 @@ class ComponentWithTemplateRef { changeDetection: ChangeDetectionStrategy.Eager, }) class PizzaMsg { + @Input() flavor = 'unknown'; dialogRef = inject>(DialogRef); dialogInjector = inject(Injector); directionality = inject(Directionality); diff --git a/src/cdk/dialog/dialog.ts b/src/cdk/dialog/dialog.ts index 41a3cfde4051..7c67e769399f 100644 --- a/src/cdk/dialog/dialog.ts +++ b/src/cdk/dialog/dialog.ts @@ -302,7 +302,13 @@ export class Dialog implements OnDestroy { } else { const injector = this._createInjector(config, dialogRef, dialogContainer, this._injector); const contentRef = dialogContainer.attachComponentPortal( - new ComponentPortal(componentOrTemplateRef, config.viewContainerRef, injector), + new ComponentPortal( + componentOrTemplateRef, + config.viewContainerRef, + injector, + null, + config.bindings, + ), ); (dialogRef as {componentRef: ComponentRef}).componentRef = contentRef; (dialogRef as {componentInstance: C}).componentInstance = contentRef.instance; From 0e1aec81c61e1cea82841ed573925d0f554badd8 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 24 Apr 2026 11:01:56 +0200 Subject: [PATCH 2/3] feat(material/bottom-sheet): add the ability to pass bindings Adds the ability to pass a `Binding[]` to the component being rendered. --- goldens/material/bottom-sheet/index.api.md | 2 ++ src/material/bottom-sheet/bottom-sheet-config.ts | 8 +++++++- src/material/bottom-sheet/bottom-sheet.spec.ts | 12 ++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/goldens/material/bottom-sheet/index.api.md b/goldens/material/bottom-sheet/index.api.md index 372d9a9a5e4a..82c18018fbeb 100644 --- a/goldens/material/bottom-sheet/index.api.md +++ b/goldens/material/bottom-sheet/index.api.md @@ -4,6 +4,7 @@ ```ts +import { Binding } from '@angular/core'; import { CdkDialogContainer } from '@angular/cdk/dialog'; import { ComponentRef } from '@angular/core'; import { ComponentType } from '@angular/cdk/portal'; @@ -53,6 +54,7 @@ export class MatBottomSheetConfig { ariaModal?: boolean; autoFocus?: AutoFocusTarget | string | boolean; backdropClass?: string; + bindings?: Binding[]; closeOnNavigation?: boolean; data?: D | null; direction?: Direction; diff --git a/src/material/bottom-sheet/bottom-sheet-config.ts b/src/material/bottom-sheet/bottom-sheet-config.ts index 123d166b4c03..dd7b6e5fc737 100644 --- a/src/material/bottom-sheet/bottom-sheet-config.ts +++ b/src/material/bottom-sheet/bottom-sheet-config.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import {InjectionToken, Injector, ViewContainerRef} from '@angular/core'; +import {Binding, InjectionToken, Injector, ViewContainerRef} from '@angular/core'; import {Direction} from '@angular/cdk/bidi'; import {ScrollStrategy} from '@angular/cdk/overlay'; import {RestoreFocusValue} from '@angular/cdk/dialog'; @@ -86,4 +86,10 @@ export class MatBottomSheetConfig { /** Maximum height for the bottom sheet. If a number is provided, assumes pixel units. */ maxHeight?: number | string; + + /** + * Bindings to apply to the component rendered inside the dialog. + * Does nothing for template-based dialogs. + */ + bindings?: Binding[]; } diff --git a/src/material/bottom-sheet/bottom-sheet.spec.ts b/src/material/bottom-sheet/bottom-sheet.spec.ts index 8063fc4d5340..e9cf9d5cbe01 100644 --- a/src/material/bottom-sheet/bottom-sheet.spec.ts +++ b/src/material/bottom-sheet/bottom-sheet.spec.ts @@ -17,6 +17,7 @@ import { Directive, Injectable, Injector, + Input, NgModule, TemplateRef, ViewChild, @@ -24,6 +25,7 @@ import { ViewEncapsulation, forwardRef, inject, + inputBinding, ChangeDetectionStrategy, } from '@angular/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; @@ -506,6 +508,15 @@ describe('MatBottomSheet', () => { expect(bottomSheetRef.instance.data).toBeNull(); }).not.toThrow(); }); + + it('should be able to apply bindings', () => { + const bottomSheetRef = bottomSheet.open(PizzaMsg, { + bindings: [inputBinding('flavor', () => 'pepperoni')], + }); + viewContainerFixture.detectChanges(); + + expect(bottomSheetRef.instance.flavor).toBe('pepperoni'); + }); }); describe('disableClose option', () => { @@ -1055,6 +1066,7 @@ class ComponentWithTemplateRef { changeDetection: ChangeDetectionStrategy.Eager, }) class PizzaMsg { + @Input() flavor = 'unknown'; bottomSheetRef = inject>(MatBottomSheetRef); injector = inject(Injector); directionality = inject(Directionality); From 8116e11760efb8932f4c467b082ef579ea3b3a24 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 24 Apr 2026 11:02:10 +0200 Subject: [PATCH 3/3] feat(material/dialog): add the ability to pass bindings Adds the ability to pass a `Binding[]` to the component being rendered. Fixes #28791. --- goldens/material/dialog/index.api.md | 2 ++ goldens/material/dialog/testing/index.api.md | 1 + src/material/dialog/dialog-config.ts | 8 ++++++-- src/material/dialog/dialog.spec.ts | 12 ++++++++++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/goldens/material/dialog/index.api.md b/goldens/material/dialog/index.api.md index bff4cccabb64..95b45db02dc8 100644 --- a/goldens/material/dialog/index.api.md +++ b/goldens/material/dialog/index.api.md @@ -4,6 +4,7 @@ ```ts +import { Binding } from '@angular/core'; import { CdkDialogContainer } from '@angular/cdk/dialog'; import { ComponentPortal } from '@angular/cdk/portal'; import { ComponentRef } from '@angular/core'; @@ -125,6 +126,7 @@ export class MatDialogConfig { ariaModal?: boolean; autoFocus?: AutoFocusTarget | string | boolean; backdropClass?: string | string[]; + bindings?: Binding[]; closeOnNavigation?: boolean; closePredicate?: (result: Result | undefined, config: Config, componentInstance: Component | null) => boolean; data?: D | null; diff --git a/goldens/material/dialog/testing/index.api.md b/goldens/material/dialog/testing/index.api.md index 5ee65ad0b2aa..b9220f42762c 100644 --- a/goldens/material/dialog/testing/index.api.md +++ b/goldens/material/dialog/testing/index.api.md @@ -6,6 +6,7 @@ import * as _angular_cdk_testing from '@angular/cdk/testing'; import { BaseHarnessFilters } from '@angular/cdk/testing'; +import { Binding } from '@angular/core'; import { CdkDialogContainer } from '@angular/cdk/dialog'; import { ComponentHarnessConstructor } from '@angular/cdk/testing'; import { ComponentPortal } from '@angular/cdk/portal'; diff --git a/src/material/dialog/dialog-config.ts b/src/material/dialog/dialog-config.ts index 899e0e1a58ce..0ebf4ee37b68 100644 --- a/src/material/dialog/dialog-config.ts +++ b/src/material/dialog/dialog-config.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import {ViewContainerRef, Injector} from '@angular/core'; +import {ViewContainerRef, Injector, Binding} from '@angular/core'; import {Direction} from '@angular/cdk/bidi'; import {ScrollStrategy} from '@angular/cdk/overlay'; import {DialogConfig, RestoreFocusValue} from '@angular/cdk/dialog'; @@ -159,5 +159,9 @@ export class MatDialogConfig { */ exitAnimationDuration?: string | number; - // TODO(jelbourn): add configuration for lifecycle hooks, ARIA labelling. + /** + * Bindings to apply to the component rendered inside the dialog. + * Does nothing for template-based dialogs. + */ + bindings?: Binding[]; } diff --git a/src/material/dialog/dialog.spec.ts b/src/material/dialog/dialog.spec.ts index 665f8fa43085..2279305fcf8e 100644 --- a/src/material/dialog/dialog.spec.ts +++ b/src/material/dialog/dialog.spec.ts @@ -20,6 +20,7 @@ import { Directive, Injectable, Injector, + Input, NgModule, TemplateRef, ViewChild, @@ -28,6 +29,7 @@ import { forwardRef, signal, inject, + inputBinding, } from '@angular/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; @@ -736,6 +738,15 @@ describe('MatDialog', () => { expect(dialogRef.componentInstance.data).toBeNull(); }).not.toThrow(); }); + + it('should be able to apply bindings', () => { + const dialogRef = dialog.open(PizzaMsg, { + bindings: [inputBinding('flavor', () => 'pepperoni')], + }); + viewContainerFixture.detectChanges(); + + expect(dialogRef.componentInstance!.flavor).toBe('pepperoni'); + }); }); it('should not keep a reference to the component after the dialog is closed', async () => { @@ -2340,6 +2351,7 @@ class ComponentWithTemplateRef { changeDetection: ChangeDetectionStrategy.Eager, }) class PizzaMsg { + @Input() flavor = 'unknown'; dialogRef = inject>(MatDialogRef); dialogInjector = inject(Injector); directionality = inject(Directionality);