Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion goldens/cdk/dialog/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export class DialogConfig<D = unknown, R = unknown, C extends DialogContainer =
backdropClass?: string | string[];
bindings?: Binding[];
closeOnDestroy?: boolean;
closeOnNavigation?: boolean;
closeOnNavigation?: OverlayDisposeOnNavigation;
closeOnOverlayDetachments?: boolean;
closePredicate?: <Result = unknown, Component = unknown, Config extends DialogConfig = DialogConfig>(result: Result | undefined, config: Config, componentInstance: Component | null) => boolean;
container?: Type<C> | {
Expand Down
9 changes: 6 additions & 3 deletions goldens/cdk/overlay/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
detachOverlay(): void;
get dir(): Direction;
disableClose: boolean;
disposeOnNavigation: boolean;
disposeOnNavigation: OverlayDisposeOnNavigation;
flexibleDimensions: boolean;
growAfterOpen: boolean;
hasBackdrop: boolean;
Expand Down Expand Up @@ -114,7 +114,7 @@ export interface CdkConnectedOverlayConfig {
// (undocumented)
disableClose?: boolean;
// (undocumented)
disposeOnNavigation?: boolean;
disposeOnNavigation?: OverlayDisposeOnNavigation;
// (undocumented)
flexibleDimensions?: boolean;
// (undocumented)
Expand Down Expand Up @@ -391,7 +391,7 @@ export class OverlayConfig {
backdropClass?: string | string[];
direction?: Direction | Directionality;
disableAnimations?: boolean;
disposeOnNavigation?: boolean;
disposeOnNavigation?: OverlayDisposeOnNavigation;
eventPredicate?: (event: Event) => boolean;
hasBackdrop?: boolean;
height?: number | string;
Expand Down Expand Up @@ -440,6 +440,9 @@ export interface OverlayDefaultConfig {
usePopover?: boolean;
}

// @public
export type OverlayDisposeOnNavigation = boolean | 'url-change' | 'pop-state';

// @public
export class OverlayKeyboardDispatcher extends BaseOverlayDispatcher {
add(overlayRef: OverlayRef): void;
Expand Down
3 changes: 2 additions & 1 deletion goldens/material/bottom-sheet/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { InjectionToken } from '@angular/core';
import { Injector } from '@angular/core';
import { Observable } from 'rxjs';
import { OnDestroy } from '@angular/core';
import { OverlayDisposeOnNavigation } from '@angular/cdk/overlay';
import { RestoreFocusValue } from '@angular/cdk/dialog';
import { ScrollStrategy } from '@angular/cdk/overlay';
import { TemplateRef } from '@angular/core';
Expand Down Expand Up @@ -55,7 +56,7 @@ export class MatBottomSheetConfig<D = any> {
autoFocus?: AutoFocusTarget | string | boolean;
backdropClass?: string;
bindings?: Binding[];
closeOnNavigation?: boolean;
closeOnNavigation?: OverlayDisposeOnNavigation;
data?: D | null;
direction?: Direction;
disableClose?: boolean;
Expand Down
3 changes: 2 additions & 1 deletion goldens/material/dialog/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { Observable } from 'rxjs';
import { OnChanges } from '@angular/core';
import { OnDestroy } from '@angular/core';
import { OnInit } from '@angular/core';
import { OverlayDisposeOnNavigation } from '@angular/cdk/overlay';
import { RestoreFocusValue } from '@angular/cdk/dialog';
import { ScrollStrategy } from '@angular/cdk/overlay';
import { SimpleChanges } from '@angular/core';
Expand Down Expand Up @@ -127,7 +128,7 @@ export class MatDialogConfig<D = any> {
autoFocus?: AutoFocusTarget | string | boolean;
backdropClass?: string | string[];
bindings?: Binding[];
closeOnNavigation?: boolean;
closeOnNavigation?: OverlayDisposeOnNavigation;
closePredicate?: <Result = unknown, Component = unknown, Config extends DialogConfig = MatDialogConfig>(result: Result | undefined, config: Config, componentInstance: Component | null) => boolean;
data?: D | null;
delayFocusTrap?: boolean;
Expand Down
1 change: 1 addition & 0 deletions goldens/material/dialog/testing/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import * as i0 from '@angular/core';
import { Injector } from '@angular/core';
import { Observable } from 'rxjs';
import { OnDestroy } from '@angular/core';
import { OverlayDisposeOnNavigation } from '@angular/cdk/overlay';
import { RestoreFocusValue } from '@angular/cdk/dialog';
import { ScrollStrategy } from '@angular/cdk/overlay';
import { Subject } from 'rxjs';
Expand Down
10 changes: 3 additions & 7 deletions src/cdk/dialog/dialog-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import {ViewContainerRef, Injector, StaticProvider, Type, Binding} from '@angular/core';
import {Direction} from '../bidi';
import {PositionStrategy, ScrollStrategy} from '../overlay';
import {OverlayDisposeOnNavigation, PositionStrategy, ScrollStrategy} from '../overlay';
import {Observable} from 'rxjs';
import {BasePortalOutlet} from '../portal';
import {FocusOrigin} from '../a11y';
Expand Down Expand Up @@ -140,12 +140,8 @@ export class DialogConfig<D = unknown, R = unknown, C extends DialogContainer =
*/
scrollStrategy?: ScrollStrategy;

/**
* Whether the dialog should close when the user navigates backwards or forwards through browser
* history. This does not apply to navigation via anchor element unless using URL-hash based
* routing (`HashLocationStrategy` in the Angular router).
*/
closeOnNavigation?: boolean = true;
/** Whether the dialog should be disposed of when the user navigates. */
closeOnNavigation?: OverlayDisposeOnNavigation = true;

/**
* Whether the dialog should close when the dialog service is destroyed. This is useful if
Expand Down
19 changes: 13 additions & 6 deletions src/cdk/overlay/overlay-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ import {PositionStrategy} from './position/position-strategy';
import {Direction, Directionality} from '../bidi';
import {ScrollStrategy, NoopScrollStrategy} from './scroll/index';

/**
* Value that can be used to configure the behavior of `OverlayConfig.disposeOnNavigation`.
* The value correspond to the following:
* - `true` or `pop-state` - Overlay is only disposed when the back/forward browser buttons are
* pressed.
* - `false` - Overlay does nothing on navigations.
* - `url-change` - Overlay closes on any URL change. Note that this may close overlays opened
* from route resolvers immediately.
*/
export type OverlayDisposeOnNavigation = boolean | 'url-change' | 'pop-state';

/** Initial configuration used when creating an overlay. */
export class OverlayConfig {
/** Strategy with which to position the overlay. */
Expand Down Expand Up @@ -54,12 +65,8 @@ export class OverlayConfig {
*/
direction?: Direction | Directionality;

/**
* Whether the overlay should be disposed of when the user goes backwards/forwards in history.
* Note that this usually doesn't include clicking on links (unless the user is using
* the `HashLocationStrategy`).
*/
disposeOnNavigation?: boolean = false;
/** Whether the overlay should be disposed of when the user navigates. */
disposeOnNavigation?: OverlayDisposeOnNavigation = false;

/**
* Whether the overlay should be rendered as a native popover element,
Expand Down
12 changes: 8 additions & 4 deletions src/cdk/overlay/overlay-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {_getEventTarget} from '../platform';
import {Subscription} from 'rxjs';
import {takeWhile} from 'rxjs/operators';
import {createOverlayRef, OVERLAY_DEFAULT_CONFIG} from './overlay';
import {OverlayConfig} from './overlay-config';
import {OverlayConfig, OverlayDisposeOnNavigation} from './overlay-config';
import {OverlayRef} from './overlay-ref';
import {ConnectedOverlayPositionChange, ViewportMargin} from './position/connected-position';
import {
Expand Down Expand Up @@ -124,7 +124,7 @@ export interface CdkConnectedOverlayConfig {
flexibleDimensions?: boolean;
growAfterOpen?: boolean;
push?: boolean;
disposeOnNavigation?: boolean;
disposeOnNavigation?: OverlayDisposeOnNavigation;
usePopover?: FlexibleOverlayPopoverLocation | null;
matchWidth?: boolean;
}
Expand Down Expand Up @@ -246,8 +246,12 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
@Input({alias: 'cdkConnectedOverlayPush', transform: booleanAttribute}) push: boolean = false;

/** Whether the overlay should be disposed of when the user goes backwards/forwards in history. */
@Input({alias: 'cdkConnectedOverlayDisposeOnNavigation', transform: booleanAttribute})
disposeOnNavigation: boolean = false;
@Input({
alias: 'cdkConnectedOverlayDisposeOnNavigation',
transform: (value: unknown): OverlayDisposeOnNavigation =>
value === 'url-change' || value === 'pop-state' ? value : booleanAttribute(value),
})
disposeOnNavigation: OverlayDisposeOnNavigation = false;

/** Whether the connected overlay should be rendered inside a popover element or the overlay container. */
@Input({alias: 'cdkConnectedOverlayUsePopover'})
Expand Down
18 changes: 12 additions & 6 deletions src/cdk/overlay/overlay-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
signal,
untracked,
} from '@angular/core';
import {Observable, Subject, Subscription, SubscriptionLike} from 'rxjs';
import {Observable, Subject} from 'rxjs';
import {Direction, Directionality} from '../bidi';
import {coerceArray, coerceCssPixelValue} from '../coercion';
import {ComponentPortal, Portal, PortalOutlet, TemplatePortal} from '../portal';
Expand Down Expand Up @@ -54,7 +54,7 @@ export class OverlayRef implements PortalOutlet {
private readonly _detachments = new Subject<void>();
private _positionStrategy: PositionStrategy | undefined;
private _scrollStrategy: ScrollStrategy | undefined;
private _locationChanges: SubscriptionLike = Subscription.EMPTY;
private _locationChanges: (() => void) | undefined;
private _backdropRef: BackdropRef | null = null;
private _detachContentMutationObserver: MutationObserver | undefined;
private _detachContentAfterRenderRef: AfterRenderRef | undefined;
Expand Down Expand Up @@ -194,8 +194,14 @@ export class OverlayRef implements PortalOutlet {
// Track this overlay by the keyboard dispatcher
this._keyboardDispatcher.add(this);

if (this._config.disposeOnNavigation) {
this._locationChanges = this._location.subscribe(() => this.dispose());
if (
this._config.disposeOnNavigation === true ||
this._config.disposeOnNavigation === 'pop-state'
) {
const subscription = this._location.subscribe(() => this.dispose());
this._locationChanges = () => subscription.unsubscribe();
} else if (this._config.disposeOnNavigation === 'url-change') {
this._locationChanges = this._location.onUrlChange(() => this.dispose());
}

this._outsideClickDispatcher.add(this);
Expand Down Expand Up @@ -258,7 +264,7 @@ export class OverlayRef implements PortalOutlet {
// Keeping the host element in the DOM can cause scroll jank, because it still gets
// rendered, even though it's transparent and unclickable which is why we remove it.
this._detachContentWhenEmpty();
this._locationChanges.unsubscribe();
this._locationChanges?.();
this._outsideClickDispatcher.remove(this);

untracked(() => {
Expand All @@ -282,7 +288,7 @@ export class OverlayRef implements PortalOutlet {

this._disposeScrollStrategy();
this._backdropRef?.dispose();
this._locationChanges.unsubscribe();
this._locationChanges?.();
this._keyboardDispatcher.remove(this);
this._portalOutlet.dispose();
this._attachments.complete();
Expand Down
10 changes: 3 additions & 7 deletions src/material/bottom-sheet/bottom-sheet-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import {Binding, InjectionToken, Injector, ViewContainerRef} from '@angular/core';
import {Direction} from '@angular/cdk/bidi';
import {ScrollStrategy} from '@angular/cdk/overlay';
import {OverlayDisposeOnNavigation, ScrollStrategy} from '@angular/cdk/overlay';
import {RestoreFocusValue} from '@angular/cdk/dialog';

/** Options for where to set focus to automatically on dialog open */
Expand Down Expand Up @@ -58,12 +58,8 @@ export class MatBottomSheetConfig<D = any> {
*/
ariaModal?: boolean = false;

/**
* Whether the bottom sheet should close when the user goes backwards/forwards in history.
* Note that this usually doesn't include clicking on links (unless the user is using
* the `HashLocationStrategy`).
*/
closeOnNavigation?: boolean = true;
/** Whether the bottom sheet should be disposed of when the user navigates. */
closeOnNavigation?: OverlayDisposeOnNavigation = true;

/**
* Where the bottom sheet should focus on open.
Expand Down
10 changes: 3 additions & 7 deletions src/material/dialog/dialog-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import {ViewContainerRef, Injector, Binding} from '@angular/core';
import {Direction} from '@angular/cdk/bidi';
import {ScrollStrategy} from '@angular/cdk/overlay';
import {OverlayDisposeOnNavigation, ScrollStrategy} from '@angular/cdk/overlay';
import {DialogConfig, RestoreFocusValue} from '@angular/cdk/dialog';

/** Options for where to set focus to automatically on dialog open */
Expand Down Expand Up @@ -138,12 +138,8 @@ export class MatDialogConfig<D = any> {
/** Scroll strategy to be used for the dialog. */
scrollStrategy?: ScrollStrategy;

/**
* Whether the dialog should close when the user goes backwards/forwards in history.
* Note that this usually doesn't include clicking on links (unless the user is using
* the `HashLocationStrategy`).
*/
closeOnNavigation?: boolean = true;
/** Whether the bottom sheet should be disposed of when the user navigates. */
closeOnNavigation?: OverlayDisposeOnNavigation = true;

/**
* Duration of the enter animation in ms.
Expand Down
Loading