mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(overlay): allow for object to be passed to the OverlayState constructor (#6615)
Allows for a config object to be passed to the `OverlayState` constructor. This makes the longer configurations a bit more convenient to use.
This commit is contained in:
committed by
Jeremy Elbourn
parent
21c68ad95e
commit
fe37cb2551
@@ -272,7 +272,12 @@ export class ConnectedOverlayDirective implements OnDestroy, OnChanges {
|
||||
|
||||
/** Builds the overlay config based on the directive's inputs */
|
||||
private _buildConfig(): OverlayState {
|
||||
let overlayConfig = new OverlayState();
|
||||
const positionStrategy = this._position = this._createPositionStrategy();
|
||||
const overlayConfig = new OverlayState({
|
||||
positionStrategy,
|
||||
scrollStrategy: this.scrollStrategy,
|
||||
hasBackdrop: this.hasBackdrop
|
||||
});
|
||||
|
||||
if (this.width || this.width === 0) {
|
||||
overlayConfig.width = this.width;
|
||||
@@ -290,16 +295,10 @@ export class ConnectedOverlayDirective implements OnDestroy, OnChanges {
|
||||
overlayConfig.minHeight = this.minHeight;
|
||||
}
|
||||
|
||||
overlayConfig.hasBackdrop = this.hasBackdrop;
|
||||
|
||||
if (this.backdropClass) {
|
||||
overlayConfig.backdropClass = this.backdropClass;
|
||||
}
|
||||
|
||||
this._position = this._createPositionStrategy() as ConnectedPositionStrategy;
|
||||
overlayConfig.positionStrategy = this._position;
|
||||
overlayConfig.scrollStrategy = this.scrollStrategy;
|
||||
|
||||
return overlayConfig;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,9 @@ export class OverlayRef implements PortalHost {
|
||||
private _state: OverlayState,
|
||||
private _ngZone: NgZone) {
|
||||
|
||||
_state.scrollStrategy.attach(this);
|
||||
if (_state.scrollStrategy) {
|
||||
_state.scrollStrategy.attach(this);
|
||||
}
|
||||
}
|
||||
|
||||
/** The overlay's HTML element */
|
||||
@@ -54,7 +56,10 @@ export class OverlayRef implements PortalHost {
|
||||
this.updateSize();
|
||||
this.updateDirection();
|
||||
this.updatePosition();
|
||||
this._state.scrollStrategy.enable();
|
||||
|
||||
if (this._state.scrollStrategy) {
|
||||
this._state.scrollStrategy.enable();
|
||||
}
|
||||
|
||||
// Enable pointer events for the overlay pane element.
|
||||
this._togglePointerEvents(true);
|
||||
@@ -89,7 +94,10 @@ export class OverlayRef implements PortalHost {
|
||||
// This is necessary because otherwise the pane element will cover the page and disable
|
||||
// pointer events therefore. Depends on the position strategy and the applied pane boundaries.
|
||||
this._togglePointerEvents(false);
|
||||
this._state.scrollStrategy.disable();
|
||||
|
||||
if (this._state.scrollStrategy) {
|
||||
this._state.scrollStrategy.disable();
|
||||
}
|
||||
|
||||
let detachmentResult = this._portalHost.detach();
|
||||
|
||||
@@ -107,7 +115,10 @@ export class OverlayRef implements PortalHost {
|
||||
this._state.positionStrategy.dispose();
|
||||
}
|
||||
|
||||
this._state.scrollStrategy.disable();
|
||||
if (this._state.scrollStrategy) {
|
||||
this._state.scrollStrategy.disable();
|
||||
}
|
||||
|
||||
this.detachBackdrop();
|
||||
this._portalHost.dispose();
|
||||
this._attachments.complete();
|
||||
|
||||
@@ -18,10 +18,10 @@ import {NoopScrollStrategy} from './scroll/noop-scroll-strategy';
|
||||
*/
|
||||
export class OverlayState {
|
||||
/** Strategy with which to position the overlay. */
|
||||
positionStrategy: PositionStrategy;
|
||||
positionStrategy?: PositionStrategy;
|
||||
|
||||
/** Strategy to be used when handling scroll events while the overlay is open. */
|
||||
scrollStrategy: ScrollStrategy = new NoopScrollStrategy();
|
||||
scrollStrategy?: ScrollStrategy = new NoopScrollStrategy();
|
||||
|
||||
/** Custom class to add to the overlay pane. */
|
||||
panelClass?: string | string[] = '';
|
||||
@@ -53,6 +53,12 @@ export class OverlayState {
|
||||
/** The direction of the text in the overlay panel. */
|
||||
direction?: Direction = 'ltr';
|
||||
|
||||
constructor(state?: OverlayState) {
|
||||
if (state) {
|
||||
Object.keys(state).forEach(key => this[key] = state[key]);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jelbourn): configuration still to add
|
||||
// - focus trap
|
||||
// - disable pointer events
|
||||
|
||||
@@ -133,8 +133,7 @@ describe('Overlay', () => {
|
||||
});
|
||||
|
||||
it('should set the direction', () => {
|
||||
const state = new OverlayState();
|
||||
state.direction = 'rtl';
|
||||
const state = new OverlayState({direction: 'rtl'});
|
||||
|
||||
overlay.create(state).attach(componentPortal);
|
||||
|
||||
@@ -153,10 +152,7 @@ describe('Overlay', () => {
|
||||
});
|
||||
|
||||
it('should emit the attachment event after everything is added to the DOM', () => {
|
||||
let state = new OverlayState();
|
||||
|
||||
state.hasBackdrop = true;
|
||||
|
||||
let state = new OverlayState({hasBackdrop: true});
|
||||
let overlayRef = overlay.create(state);
|
||||
|
||||
overlayRef.attachments().subscribe(() => {
|
||||
@@ -415,9 +411,8 @@ describe('Overlay', () => {
|
||||
|
||||
describe('panelClass', () => {
|
||||
it('should apply a custom overlay pane class', () => {
|
||||
const config = new OverlayState();
|
||||
const config = new OverlayState({panelClass: 'custom-panel-class'});
|
||||
|
||||
config.panelClass = 'custom-panel-class';
|
||||
overlay.create(config).attach(componentPortal);
|
||||
viewContainerFixture.detectChanges();
|
||||
|
||||
@@ -426,9 +421,8 @@ describe('Overlay', () => {
|
||||
});
|
||||
|
||||
it('should be able to apply multiple classes', () => {
|
||||
const config = new OverlayState();
|
||||
const config = new OverlayState({panelClass: ['custom-class-one', 'custom-class-two']});
|
||||
|
||||
config.panelClass = ['custom-class-one', 'custom-class-two'];
|
||||
overlay.create(config).attach(componentPortal);
|
||||
viewContainerFixture.detectChanges();
|
||||
|
||||
@@ -445,8 +439,8 @@ describe('Overlay', () => {
|
||||
let overlayRef: OverlayRef;
|
||||
|
||||
beforeEach(() => {
|
||||
config = new OverlayState();
|
||||
fakeScrollStrategy = config.scrollStrategy = new FakeScrollStrategy();
|
||||
fakeScrollStrategy = new FakeScrollStrategy();
|
||||
config = new OverlayState({scrollStrategy: fakeScrollStrategy});
|
||||
overlayRef = overlay.create(config);
|
||||
});
|
||||
|
||||
|
||||
@@ -23,9 +23,8 @@ describe('BlockScrollStrategy', () => {
|
||||
}));
|
||||
|
||||
beforeEach(inject([Overlay, ViewportRuler], (overlay: Overlay, viewportRuler: ViewportRuler) => {
|
||||
let overlayState = new OverlayState();
|
||||
let overlayState = new OverlayState({scrollStrategy: overlay.scrollStrategies.block()});
|
||||
|
||||
overlayState.scrollStrategy = overlay.scrollStrategies.block();
|
||||
overlayRef = overlay.create(overlayState);
|
||||
componentPortal = new ComponentPortal(FocacciaMsg);
|
||||
|
||||
|
||||
@@ -33,8 +33,7 @@ describe('CloseScrollStrategy', () => {
|
||||
}));
|
||||
|
||||
beforeEach(inject([Overlay], (overlay: Overlay) => {
|
||||
let overlayState = new OverlayState();
|
||||
overlayState.scrollStrategy = overlay.scrollStrategies.close();
|
||||
let overlayState = new OverlayState({scrollStrategy: overlay.scrollStrategies.close()});
|
||||
overlayRef = overlay.create(overlayState);
|
||||
componentPortal = new ComponentPortal(MozarellaMsg);
|
||||
}));
|
||||
|
||||
@@ -33,8 +33,7 @@ describe('RepositionScrollStrategy', () => {
|
||||
}));
|
||||
|
||||
beforeEach(inject([Overlay], (overlay: Overlay) => {
|
||||
let overlayState = new OverlayState();
|
||||
overlayState.scrollStrategy = overlay.scrollStrategies.reposition();
|
||||
let overlayState = new OverlayState({scrollStrategy: overlay.scrollStrategies.reposition()});
|
||||
overlayRef = overlay.create(overlayState);
|
||||
componentPortal = new ComponentPortal(PastaMsg);
|
||||
}));
|
||||
|
||||
@@ -11,9 +11,10 @@ scroll strategy, to the `OverlayState`. By default, all overlays will use the `n
|
||||
doesn't do anything. The other available strategies are `reposition`, `block` and `close`:
|
||||
|
||||
```ts
|
||||
let overlayState = new OverlayState();
|
||||
let overlayState = new OverlayState({
|
||||
scrollStrategy: overlay.scrollStrategies.block()
|
||||
});
|
||||
|
||||
overlayState.scrollStrategy = overlay.scrollStrategies.block();
|
||||
this._overlay.create(overlayState).attach(yourPortal);
|
||||
```
|
||||
|
||||
|
||||
@@ -74,10 +74,9 @@ export class OverlayDemo {
|
||||
{originX: 'start', originY: 'bottom'},
|
||||
{overlayX: 'start', overlayY: 'top'} );
|
||||
|
||||
let config = new OverlayState();
|
||||
config.positionStrategy = strategy;
|
||||
|
||||
let config = new OverlayState({positionStrategy: strategy});
|
||||
let overlayRef = this.overlay.create(config);
|
||||
|
||||
overlayRef.attach(new ComponentPortal(SpagettiPanel, this.viewContainerRef));
|
||||
}
|
||||
|
||||
@@ -88,22 +87,18 @@ export class OverlayDemo {
|
||||
{originX: 'start', originY: 'bottom'},
|
||||
{overlayX: 'end', overlayY: 'top'} );
|
||||
|
||||
let config = new OverlayState();
|
||||
config.positionStrategy = strategy;
|
||||
|
||||
let config = new OverlayState({positionStrategy: strategy});
|
||||
let overlayRef = this.overlay.create(config);
|
||||
|
||||
overlayRef.attach(this.tortelliniTemplate);
|
||||
}
|
||||
|
||||
openPanelWithBackdrop() {
|
||||
let config = new OverlayState();
|
||||
|
||||
config.positionStrategy = this.overlay.position()
|
||||
.global()
|
||||
.centerHorizontally();
|
||||
config.hasBackdrop = true;
|
||||
config.backdropClass = 'cdk-overlay-transparent-backdrop';
|
||||
let config = new OverlayState({
|
||||
hasBackdrop: true,
|
||||
backdropClass: 'cdk-overlay-transparent-backdrop',
|
||||
positionStrategy: this.overlay.position().global().centerHorizontally()
|
||||
});
|
||||
|
||||
let overlayRef = this.overlay.create(config);
|
||||
overlayRef.attach(this.templatePortals.first);
|
||||
|
||||
@@ -468,12 +468,12 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
|
||||
}
|
||||
|
||||
private _getOverlayConfig(): OverlayState {
|
||||
const overlayState = new OverlayState();
|
||||
overlayState.positionStrategy = this._getOverlayPosition();
|
||||
overlayState.width = this._getHostWidth();
|
||||
overlayState.direction = this._dir ? this._dir.value : 'ltr';
|
||||
overlayState.scrollStrategy = this._scrollStrategy();
|
||||
return overlayState;
|
||||
return new OverlayState({
|
||||
positionStrategy: this._getOverlayPosition(),
|
||||
scrollStrategy: this._scrollStrategy(),
|
||||
width: this._getHostWidth(),
|
||||
direction: this._dir ? this._dir.value : 'ltr'
|
||||
});
|
||||
}
|
||||
|
||||
private _getOverlayPosition(): PositionStrategy {
|
||||
|
||||
@@ -321,12 +321,13 @@ export class MdDatepicker<D> implements OnDestroy {
|
||||
|
||||
/** Create the popup. */
|
||||
private _createPopup(): void {
|
||||
const overlayState = new OverlayState();
|
||||
overlayState.positionStrategy = this._createPopupPositionStrategy();
|
||||
overlayState.hasBackdrop = true;
|
||||
overlayState.backdropClass = 'md-overlay-transparent-backdrop';
|
||||
overlayState.direction = this._dir ? this._dir.value : 'ltr';
|
||||
overlayState.scrollStrategy = this._scrollStrategy();
|
||||
const overlayState = new OverlayState({
|
||||
positionStrategy: this._createPopupPositionStrategy(),
|
||||
hasBackdrop: true,
|
||||
backdropClass: 'md-overlay-transparent-backdrop',
|
||||
direction: this._dir ? this._dir.value : 'ltr',
|
||||
scrollStrategy: this._scrollStrategy()
|
||||
});
|
||||
|
||||
this._popupRef = this._overlay.create(overlayState);
|
||||
}
|
||||
|
||||
+12
-10
@@ -186,17 +186,19 @@ export class MdDialog {
|
||||
* @returns The overlay configuration.
|
||||
*/
|
||||
private _getOverlayState(dialogConfig: MdDialogConfig): OverlayState {
|
||||
const overlayState = new OverlayState();
|
||||
overlayState.panelClass = dialogConfig.panelClass;
|
||||
overlayState.hasBackdrop = dialogConfig.hasBackdrop;
|
||||
overlayState.scrollStrategy = this._scrollStrategy();
|
||||
overlayState.direction = dialogConfig.direction;
|
||||
if (dialogConfig.backdropClass) {
|
||||
overlayState.backdropClass = dialogConfig.backdropClass;
|
||||
}
|
||||
overlayState.positionStrategy = this._overlay.position().global();
|
||||
const state = new OverlayState({
|
||||
positionStrategy: this._overlay.position().global(),
|
||||
scrollStrategy: this._scrollStrategy(),
|
||||
panelClass: dialogConfig.panelClass,
|
||||
hasBackdrop: dialogConfig.hasBackdrop,
|
||||
direction: dialogConfig.direction
|
||||
});
|
||||
|
||||
return overlayState;
|
||||
if (dialogConfig.backdropClass) {
|
||||
state.backdropClass = dialogConfig.backdropClass;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -322,13 +322,13 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
|
||||
* @returns OverlayState
|
||||
*/
|
||||
private _getOverlayConfig(): OverlayState {
|
||||
const overlayState = new OverlayState();
|
||||
overlayState.positionStrategy = this._getPosition();
|
||||
overlayState.hasBackdrop = !this.triggersSubmenu();
|
||||
overlayState.backdropClass = 'cdk-overlay-transparent-backdrop';
|
||||
overlayState.direction = this.dir;
|
||||
overlayState.scrollStrategy = this._scrollStrategy();
|
||||
return overlayState;
|
||||
return new OverlayState({
|
||||
positionStrategy: this._getPosition(),
|
||||
hasBackdrop: !this.triggersSubmenu(),
|
||||
backdropClass: 'cdk-overlay-transparent-backdrop',
|
||||
direction: this.dir,
|
||||
scrollStrategy: this._scrollStrategy()
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -153,9 +153,11 @@ export class MdSnackBar {
|
||||
* @param config The user-specified snack bar config.
|
||||
*/
|
||||
private _createOverlay(config: MdSnackBarConfig): OverlayRef {
|
||||
const state = new OverlayState();
|
||||
state.direction = config.direction;
|
||||
state.positionStrategy = this._overlay.position().global().centerHorizontally().bottom('0');
|
||||
const state = new OverlayState({
|
||||
direction: config.direction,
|
||||
positionStrategy: this._overlay.position().global().centerHorizontally().bottom('0')
|
||||
});
|
||||
|
||||
return this._overlay.create(state);
|
||||
}
|
||||
|
||||
|
||||
@@ -279,13 +279,13 @@ export class MdTooltip implements OnDestroy {
|
||||
|
||||
/** Create the overlay config and position strategy */
|
||||
private _createOverlay(): OverlayRef {
|
||||
let origin = this._getOrigin();
|
||||
let position = this._getOverlayPosition();
|
||||
const origin = this._getOrigin();
|
||||
const position = this._getOverlayPosition();
|
||||
|
||||
// Create connected position strategy that listens for scroll events to reposition.
|
||||
// After position changes occur and the overlay is clipped by a parent scrollable then
|
||||
// close the tooltip.
|
||||
let strategy = this._overlay.position().connectedTo(this._elementRef, origin, position);
|
||||
const strategy = this._overlay.position().connectedTo(this._elementRef, origin, position);
|
||||
strategy.withScrollableContainers(this._scrollDispatcher.getScrollContainers(this._elementRef));
|
||||
strategy.onPositionChange.subscribe(change => {
|
||||
if (change.scrollableViewProperties.isOverlayClipped &&
|
||||
@@ -294,12 +294,12 @@ export class MdTooltip implements OnDestroy {
|
||||
}
|
||||
});
|
||||
|
||||
let config = new OverlayState();
|
||||
|
||||
config.direction = this._dir ? this._dir.value : 'ltr';
|
||||
config.positionStrategy = strategy;
|
||||
config.panelClass = TOOLTIP_PANEL_CLASS;
|
||||
config.scrollStrategy = this._scrollStrategy();
|
||||
const config = new OverlayState({
|
||||
direction: this._dir ? this._dir.value : 'ltr',
|
||||
positionStrategy: strategy,
|
||||
panelClass: TOOLTIP_PANEL_CLASS,
|
||||
scrollStrategy: this._scrollStrategy()
|
||||
});
|
||||
|
||||
this._overlayRef = this._overlay.create(config);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user