Skip to content

Commit 527fc37

Browse files
authored
feat(material/bottom-sheet): add injector to MatBottomSheetConfig (#31965)
close #31951
1 parent 2d5942c commit 527fc37

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

goldens/material/bottom-sheet/index.api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import * as i1 from '@angular/cdk/dialog';
1515
import * as i2$1 from '@angular/cdk/bidi';
1616
import * as i2 from '@angular/cdk/portal';
1717
import { InjectionToken } from '@angular/core';
18+
import { Injector } from '@angular/core';
1819
import { Observable } from 'rxjs';
1920
import { OnDestroy } from '@angular/core';
2021
import { ScrollStrategy } from '@angular/cdk/overlay';
@@ -58,6 +59,7 @@ export class MatBottomSheetConfig<D = any> {
5859
disableClose?: boolean;
5960
hasBackdrop?: boolean;
6061
height?: string;
62+
injector?: Injector;
6163
maxHeight?: number | string;
6264
minHeight?: number | string;
6365
panelClass?: string | string[];

src/material/bottom-sheet/bottom-sheet-config.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9+
import {InjectionToken, Injector, ViewContainerRef} from '@angular/core';
910
import {Direction} from '@angular/cdk/bidi';
1011
import {ScrollStrategy} from '@angular/cdk/overlay';
11-
import {InjectionToken, ViewContainerRef} from '@angular/core';
1212

1313
/** Options for where to set focus to automatically on dialog open */
1414
export type AutoFocusTarget = 'dialog' | 'first-tabbable' | 'first-heading';
@@ -23,6 +23,12 @@ export class MatBottomSheetConfig<D = any> {
2323
/** The view container to place the overlay for the bottom sheet into. */
2424
viewContainerRef?: ViewContainerRef;
2525

26+
/**
27+
* Injector used for the instantiation of the component to be attached. If provided,
28+
* takes precedence over the injector indirectly provided by `ViewContainerRef`.
29+
*/
30+
injector?: Injector;
31+
2632
/** Extra CSS classes to be added to the bottom sheet container. */
2733
panelClass?: string | string[];
2834

src/material/bottom-sheet/bottom-sheet.spec.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@ import {SpyLocation} from '@angular/common/testing';
1313
import {
1414
Component,
1515
ComponentRef,
16+
createNgModuleRef,
1617
Directive,
18+
Injectable,
1719
Injector,
20+
NgModule,
1821
TemplateRef,
1922
ViewChild,
2023
ViewContainerRef,
2124
ViewEncapsulation,
25+
forwardRef,
2226
inject,
2327
} from '@angular/core';
2428
import {
@@ -987,6 +991,25 @@ describe('MatBottomSheet with default options', () => {
987991
}));
988992
});
989993

994+
describe('MatBottomSheet with explicit injector provided', () => {
995+
let overlayContainerElement: HTMLElement;
996+
let fixture: ComponentFixture<ModuleBoundBottomSheetParentComponent>;
997+
998+
beforeEach(fakeAsync(() => {
999+
overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement();
1000+
fixture = TestBed.createComponent(ModuleBoundBottomSheetParentComponent);
1001+
}));
1002+
1003+
it('should use the standalone injector and render the bottom sheet successfully', () => {
1004+
fixture.componentInstance.openBottomSheet();
1005+
fixture.detectChanges();
1006+
1007+
expect(
1008+
overlayContainerElement.querySelector('module-bound-bottom-sheet-child-component')!.innerHTML,
1009+
).toEqual('<p>Pasta</p>');
1010+
});
1011+
});
1012+
9901013
@Directive({
9911014
selector: 'dir-with-view-container',
9921015
})
@@ -1066,3 +1089,46 @@ class BottomSheetWithInjectedData {
10661089
encapsulation: ViewEncapsulation.ShadowDom,
10671090
})
10681091
class ShadowDomComponent {}
1092+
1093+
@Component({
1094+
template: '',
1095+
})
1096+
class ModuleBoundBottomSheetParentComponent {
1097+
private _injector = inject(Injector);
1098+
private _bottomSheet = inject(MatBottomSheet);
1099+
1100+
openBottomSheet(): void {
1101+
const ngModuleRef = createNgModuleRef(
1102+
ModuleBoundBottomSheetModule,
1103+
/* parentInjector */ this._injector,
1104+
);
1105+
1106+
this._bottomSheet.open(ModuleBoundBottomSheetComponent, {injector: ngModuleRef.injector});
1107+
}
1108+
}
1109+
1110+
@Injectable()
1111+
class ModuleBoundBottomSheetService {
1112+
name = 'Pasta';
1113+
}
1114+
1115+
@Component({
1116+
template:
1117+
'<module-bound-bottom-sheet-child-component></module-bound-bottom-sheet-child-component>',
1118+
imports: [forwardRef(() => ModuleBoundBottomSheetChildComponent)],
1119+
})
1120+
class ModuleBoundBottomSheetComponent {}
1121+
1122+
@Component({
1123+
selector: 'module-bound-bottom-sheet-child-component',
1124+
template: '<p>{{service.name}}</p>',
1125+
})
1126+
class ModuleBoundBottomSheetChildComponent {
1127+
service = inject(ModuleBoundBottomSheetService);
1128+
}
1129+
1130+
@NgModule({
1131+
imports: [ModuleBoundBottomSheetComponent, ModuleBoundBottomSheetChildComponent],
1132+
providers: [ModuleBoundBottomSheetService],
1133+
})
1134+
class ModuleBoundBottomSheetModule {}

0 commit comments

Comments
 (0)