Skip to content

Commit a6c6eae

Browse files
committed
fix(overlay): injection errors for scroll strategy providers in lazy-loaded modules
Fixes injection errors being thrown by the overlay-based providers that have injection tokens for the default scroll strategy. The error comes from the fact that the scroll strategies were being provided at the root, whereas the `Overlay` provider was provided normally, causing it to be missing when a module is lazy-loaded. Fixes #10820.
1 parent 81b6a78 commit a6c6eae

File tree

11 files changed

+72
-62
lines changed

11 files changed

+72
-62
lines changed

src/cdk/overlay/overlay-directives.ts

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,13 @@ import {Direction, Directionality} from '@angular/cdk/bidi';
1010
import {coerceBooleanProperty} from '@angular/cdk/coercion';
1111
import {ESCAPE} from '@angular/cdk/keycodes';
1212
import {TemplatePortal} from '@angular/cdk/portal';
13-
import {ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling';
1413
import {
1514
Directive,
1615
ElementRef,
1716
EventEmitter,
1817
Inject,
19-
inject,
2018
InjectionToken,
2119
Input,
22-
NgZone,
2320
OnChanges,
2421
OnDestroy,
2522
Optional,
@@ -74,20 +71,12 @@ const defaultPositionList: ConnectedPosition[] = [
7471

7572
/** Injection token that determines the scroll handling while the connected overlay is open. */
7673
export const CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY =
77-
new InjectionToken<() => ScrollStrategy>('cdk-connected-overlay-scroll-strategy', {
78-
providedIn: 'root',
79-
factory: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY,
80-
});
74+
new InjectionToken<() => ScrollStrategy>('cdk-connected-overlay-scroll-strategy');
8175

82-
/** @docs-private */
83-
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
84-
// Store the injected deps here because we can't use the `inject` function outside
85-
// this function's context (including the inner function).
86-
const scrollDispatcher = inject(ScrollDispatcher);
87-
const viewportRuler = inject(ViewportRuler);
88-
const ngZone = inject(NgZone);
89-
return (config?: RepositionScrollStrategyConfig) =>
90-
new RepositionScrollStrategy(scrollDispatcher, viewportRuler, ngZone, config);
76+
/** @docs-private @deprecated @deletion-target 7.0.0 */
77+
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY(overlay: Overlay):
78+
() => ScrollStrategy {
79+
return (config?: RepositionScrollStrategyConfig) => overlay.scrollStrategies.reposition(config);
9180
}
9281

9382
/**
@@ -375,13 +364,13 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
375364
}
376365

377366

378-
/** @docs-private @deprecated @deletion-target 7.0.0 */
367+
/** @docs-private */
379368
export function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay: Overlay):
380369
() => RepositionScrollStrategy {
381370
return () => overlay.scrollStrategies.reposition();
382371
}
383372

384-
/** @docs-private @deprecated @deletion-target 7.0.0 */
373+
/** @docs-private */
385374
export const CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER = {
386375
provide: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY,
387376
deps: [Overlay],

src/cdk/overlay/overlay-module.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import {
1717
CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER,
1818
CdkConnectedOverlay,
1919
CdkOverlayOrigin,
20+
CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY,
21+
CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_FACTORY,
2022
} from './overlay-directives';
2123
import {OverlayPositionBuilder} from './position/overlay-position-builder';
2224

@@ -25,7 +27,10 @@ import {OverlayPositionBuilder} from './position/overlay-position-builder';
2527
imports: [BidiModule, PortalModule, ScrollDispatchModule],
2628
exports: [CdkConnectedOverlay, CdkOverlayOrigin, ScrollDispatchModule],
2729
declarations: [CdkConnectedOverlay, CdkOverlayOrigin],
28-
providers: [Overlay],
30+
providers: [
31+
Overlay,
32+
CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER,
33+
],
2934
})
3035
export class OverlayModule {}
3136

src/lib/autocomplete/autocomplete-module.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,25 @@
88

99
import {NgModule} from '@angular/core';
1010
import {CommonModule} from '@angular/common';
11-
import {OverlayModule} from '@angular/cdk/overlay';
11+
import {OverlayModule, Overlay} from '@angular/cdk/overlay';
1212
import {MatOptionModule, MatCommonModule} from '@angular/material/core';
1313
import {MatAutocomplete} from './autocomplete';
1414
import {
1515
MatAutocompleteTrigger,
16+
MAT_AUTOCOMPLETE_SCROLL_STRATEGY,
17+
MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY,
1618
} from './autocomplete-trigger';
1719

1820
@NgModule({
1921
imports: [MatOptionModule, OverlayModule, MatCommonModule, CommonModule],
2022
exports: [MatAutocomplete, MatOptionModule, MatAutocompleteTrigger, MatCommonModule],
2123
declarations: [MatAutocomplete, MatAutocompleteTrigger],
24+
providers: [
25+
{
26+
provide: MAT_AUTOCOMPLETE_SCROLL_STRATEGY,
27+
deps: [Overlay],
28+
useFactory: MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY,
29+
}
30+
]
2231
})
2332
export class MatAutocompleteModule {}

src/lib/autocomplete/autocomplete-trigger.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
forwardRef,
2727
Host,
2828
Inject,
29-
inject,
3029
InjectionToken,
3130
Input,
3231
NgZone,
@@ -61,14 +60,10 @@ export const AUTOCOMPLETE_PANEL_HEIGHT = 256;
6160

6261
/** Injection token that determines the scroll handling while the autocomplete panel is open. */
6362
export const MAT_AUTOCOMPLETE_SCROLL_STRATEGY =
64-
new InjectionToken<() => ScrollStrategy>('mat-autocomplete-scroll-strategy', {
65-
providedIn: 'root',
66-
factory: MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY,
67-
});
63+
new InjectionToken<() => ScrollStrategy>('mat-autocomplete-scroll-strategy');
6864

6965
/** @docs-private */
70-
export function MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
71-
const overlay = inject(Overlay);
66+
export function MAT_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
7267
return () => overlay.scrollStrategies.reposition();
7368
}
7469

src/lib/datepicker/datepicker-module.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@
77
*/
88

99
import {A11yModule} from '@angular/cdk/a11y';
10-
import {OverlayModule} from '@angular/cdk/overlay';
10+
import {OverlayModule, Overlay} from '@angular/cdk/overlay';
1111
import {PortalModule} from '@angular/cdk/portal';
1212
import {CommonModule} from '@angular/common';
1313
import {NgModule} from '@angular/core';
1414
import {MatButtonModule} from '@angular/material/button';
1515
import {MatDialogModule} from '@angular/material/dialog';
1616
import {MatCalendar, MatCalendarHeader} from './calendar';
1717
import {MatCalendarBody} from './calendar-body';
18-
import {MatDatepicker, MatDatepickerContent} from './datepicker';
18+
import {
19+
MatDatepicker,
20+
MatDatepickerContent,
21+
MAT_DATEPICKER_SCROLL_STRATEGY,
22+
MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY,
23+
} from './datepicker';
1924
import {MatDatepickerInput} from './datepicker-input';
2025
import {MatDatepickerIntl} from './datepicker-intl';
2126
import {MatDatepickerToggle, MatDatepickerToggleIcon} from './datepicker-toggle';
@@ -61,6 +66,11 @@ import {MatYearView} from './year-view';
6166
],
6267
providers: [
6368
MatDatepickerIntl,
69+
{
70+
provide: MAT_DATEPICKER_SCROLL_STRATEGY,
71+
deps: [Overlay],
72+
useFactory: MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY,
73+
}
6474
],
6575
entryComponents: [
6676
MatDatepickerContent,

src/lib/datepicker/datepicker.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import {
2929
ElementRef,
3030
EventEmitter,
3131
Inject,
32-
inject,
3332
InjectionToken,
3433
Input,
3534
NgZone,
@@ -54,14 +53,10 @@ let datepickerUid = 0;
5453

5554
/** Injection token that determines the scroll handling while the calendar is open. */
5655
export const MAT_DATEPICKER_SCROLL_STRATEGY =
57-
new InjectionToken<() => ScrollStrategy>('mat-datepicker-scroll-strategy', {
58-
providedIn: 'root',
59-
factory: MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY,
60-
});
56+
new InjectionToken<() => ScrollStrategy>('mat-datepicker-scroll-strategy');
6157

6258
/** @docs-private */
63-
export function MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
64-
const overlay = inject(Overlay);
59+
export function MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
6560
return () => overlay.scrollStrategies.reposition();
6661
}
6762

src/lib/dialog/dialog.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import {Location} from '@angular/common';
1919
import {
2020
ComponentRef,
2121
Inject,
22-
inject,
2322
Injectable,
2423
InjectionToken,
2524
Injector,
@@ -43,14 +42,10 @@ export const MAT_DIALOG_DEFAULT_OPTIONS =
4342

4443
/** Injection token that determines the scroll handling while the dialog is open. */
4544
export const MAT_DIALOG_SCROLL_STRATEGY =
46-
new InjectionToken<() => ScrollStrategy>('mat-dialog-scroll-strategy', {
47-
providedIn: 'root',
48-
factory: MAT_DIALOG_SCROLL_STRATEGY_FACTORY,
49-
});
45+
new InjectionToken<() => ScrollStrategy>('mat-dialog-scroll-strategy');
5046

5147
/** @docs-private */
52-
export function MAT_DIALOG_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
53-
const overlay = inject(Overlay);
48+
export function MAT_DIALOG_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
5449
return () => overlay.scrollStrategies.block();
5550
}
5651

src/lib/menu/menu-module.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {OverlayModule} from '@angular/cdk/overlay';
9+
import {OverlayModule, Overlay} from '@angular/cdk/overlay';
1010
import {CommonModule} from '@angular/common';
1111
import {NgModule} from '@angular/core';
1212
import {MatCommonModule, MatRippleModule} from '@angular/material/core';
1313
import {MatMenuContent} from './menu-content';
1414
import {MatMenu} from './menu-directive';
1515
import {MatMenuItem} from './menu-item';
16-
import {MatMenuTrigger} from './menu-trigger';
16+
import {
17+
MatMenuTrigger,
18+
MAT_MENU_SCROLL_STRATEGY,
19+
MAT_MENU_SCROLL_STRATEGY_FACTORY,
20+
} from './menu-trigger';
1721

1822

1923
@NgModule({
@@ -25,5 +29,12 @@ import {MatMenuTrigger} from './menu-trigger';
2529
],
2630
exports: [MatMenu, MatMenuItem, MatMenuTrigger, MatMenuContent, MatCommonModule],
2731
declarations: [MatMenu, MatMenuItem, MatMenuTrigger, MatMenuContent],
32+
providers: [
33+
{
34+
provide: MAT_MENU_SCROLL_STRATEGY,
35+
deps: [Overlay],
36+
useFactory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
37+
}
38+
]
2839
})
2940
export class MatMenuModule {}

src/lib/menu/menu-trigger.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
ElementRef,
2727
EventEmitter,
2828
Inject,
29-
inject,
3029
InjectionToken,
3130
Input,
3231
OnDestroy,
@@ -44,14 +43,10 @@ import {MenuPositionX, MenuPositionY} from './menu-positions';
4443

4544
/** Injection token that determines the scroll handling while the menu is open. */
4645
export const MAT_MENU_SCROLL_STRATEGY =
47-
new InjectionToken<() => ScrollStrategy>('mat-menu-scroll-strategy', {
48-
providedIn: 'root',
49-
factory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
50-
});
46+
new InjectionToken<() => ScrollStrategy>('mat-menu-scroll-strategy');
5147

5248
/** @docs-private */
53-
export function MAT_MENU_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
54-
const overlay = inject(Overlay);
49+
export function MAT_MENU_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
5550
return () => overlay.scrollStrategies.reposition();
5651
}
5752

src/lib/tooltip/tooltip-module.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {OverlayModule} from '@angular/cdk/overlay';
9+
import {OverlayModule, Overlay} from '@angular/cdk/overlay';
1010
import {CommonModule} from '@angular/common';
1111
import {NgModule} from '@angular/core';
1212
import {MatCommonModule} from '@angular/material/core';
13-
import {MatTooltip, TooltipComponent} from './tooltip';
14-
13+
import {
14+
MatTooltip,
15+
TooltipComponent,
16+
MAT_TOOLTIP_SCROLL_STRATEGY,
17+
MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY,
18+
} from './tooltip';
1519

1620
@NgModule({
1721
imports: [
@@ -22,5 +26,12 @@ import {MatTooltip, TooltipComponent} from './tooltip';
2226
exports: [MatTooltip, TooltipComponent, MatCommonModule],
2327
declarations: [MatTooltip, TooltipComponent],
2428
entryComponents: [TooltipComponent],
29+
providers: [
30+
{
31+
provide: MAT_TOOLTIP_SCROLL_STRATEGY,
32+
deps: [Overlay],
33+
useFactory: MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY,
34+
}
35+
]
2536
})
2637
export class MatTooltipModule {}

src/lib/tooltip/tooltip.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import {
3333
Directive,
3434
ElementRef,
3535
Inject,
36-
inject,
3736
InjectionToken,
3837
Input,
3938
NgZone,
@@ -61,14 +60,10 @@ export function getMatTooltipInvalidPositionError(position: string) {
6160

6261
/** Injection token that determines the scroll handling while a tooltip is visible. */
6362
export const MAT_TOOLTIP_SCROLL_STRATEGY =
64-
new InjectionToken<() => ScrollStrategy>('mat-tooltip-scroll-strategy', {
65-
providedIn: 'root',
66-
factory: MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY,
67-
});
63+
new InjectionToken<() => ScrollStrategy>('mat-tooltip-scroll-strategy');
6864

6965
/** @docs-private */
70-
export function MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY(): () => ScrollStrategy {
71-
const overlay = inject(Overlay);
66+
export function MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy {
7267
return () => overlay.scrollStrategies.reposition({scrollThrottle: SCROLL_THROTTLE_MS});
7368
}
7469

0 commit comments

Comments
 (0)