or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

accessibility.mdaccordion.mdcollections-data.mddialogs.mddrag-drop.mdindex.mdlistbox.mdmenus.mdobservers.mdoverlays.mdplatform-utilities.mdportals.mdscrolling.mdtesting.mdtext-fields.md
tile.json

overlays.mddocs/

Overlays

The Angular CDK Overlay module provides a powerful system for creating positioned floating content like tooltips, dropdowns, modals, and popups. It handles positioning, z-index management, scroll behavior, and backdrop interactions.

Capabilities

Overlay Service

The main service for creating and managing overlays.

/**
 * Service for creating overlays
 */
class Overlay {
  /**
   * Create a new overlay with the given configuration
   * @param config - Overlay configuration options
   * @returns OverlayRef for managing the overlay
   */
  create(config?: OverlayConfig): OverlayRef;
  
  /**
   * Get the overlay position builder
   * @returns OverlayPositionBuilder for creating position strategies
   */
  position(): OverlayPositionBuilder;
  
  /**
   * Get available scroll strategies
   */
  scrollStrategies: ScrollStrategyOptions;
}

Usage Example:

import { Overlay, OverlayRef } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';

constructor(private overlay: Overlay) {}

openTooltip() {
  const overlayRef = this.overlay.create({
    positionStrategy: this.overlay.position()
      .flexibleConnectedTo(this.triggerElement)
      .withPositions([{
        originX: 'center',
        originY: 'bottom',
        overlayX: 'center',
        overlayY: 'top'
      }]),
    hasBackdrop: false,
    scrollStrategy: this.overlay.scrollStrategies.reposition()
  });
  
  const portal = new ComponentPortal(TooltipComponent);
  overlayRef.attach(portal);
}

Overlay Reference

Reference to a created overlay for managing its lifecycle and content.

/**
 * Reference to a created overlay
 */
class OverlayRef {
  /**
   * Attach content to the overlay
   * @param portal - Portal containing the content to attach
   * @returns Reference to the attached content
   */
  attach<T>(portal: Portal<T>): ComponentRef<T> | EmbeddedViewRef<T> | null;
  
  /**
   * Detach content from the overlay
   * @returns The detached content
   */
  detach(): any;
  
  /**
   * Dispose of the overlay and clean up resources
   */
  dispose(): void;
  
  /**
   * Whether the overlay has attached content
   * @returns True if content is attached
   */
  hasAttached(): boolean;
  
  /**
   * Observable for backdrop click events
   * @returns Observable that emits when backdrop is clicked
   */
  backdropClick(): Observable<MouseEvent>;
  
  /**
   * Observable for attachment events
   * @returns Observable that emits when content is attached
   */
  attachments(): Observable<void>;
  
  /**
   * Observable for detachment events
   * @returns Observable that emits when content is detached
   */
  detachments(): Observable<void>;
  
  /**
   * Observable for keydown events on the overlay
   * @returns Observable that emits keydown events
   */
  keydownEvents(): Observable<KeyboardEvent>;
  
  /**
   * Observable for pointer events outside the overlay
   * @returns Observable that emits outside pointer events
   */
  outsidePointerEvents(): Observable<MouseEvent>;
  
  /**
   * Get the overlay configuration
   * @returns Current overlay configuration
   */
  getConfig(): OverlayConfig;
  
  /**
   * Update the overlay position
   */
  updatePosition(): void;
  
  /**
   * Update the position strategy
   * @param strategy - New position strategy
   */
  updatePositionStrategy(strategy: PositionStrategy): void;
  
  /**
   * Update the overlay size
   * @param config - New size configuration
   */
  updateSize(config: OverlaySizeConfig): void;
}

Overlay Configuration

Configuration options for creating overlays.

/**
 * Configuration for creating an overlay
 */
class OverlayConfig {
  /** Position strategy for the overlay */
  positionStrategy?: PositionStrategy;
  
  /** Scroll strategy for the overlay */
  scrollStrategy?: ScrollStrategy;
  
  /** CSS classes to add to the overlay panel */
  panelClass?: string | string[];
  
  /** Whether the overlay has a backdrop */
  hasBackdrop?: boolean;
  
  /** CSS classes to add to the backdrop */
  backdropClass?: string | string[];
  
  /** Width of the overlay */
  width?: number | string;
  
  /** Height of the overlay */
  height?: number | string;
  
  /** Minimum width of the overlay */
  minWidth?: number | string;
  
  /** Minimum height of the overlay */
  minHeight?: number | string;
  
  /** Maximum width of the overlay */
  maxWidth?: number | string;
  
  /** Maximum height of the overlay */
  maxHeight?: number | string;
  
  /** Text direction for the overlay */
  direction?: Direction | Directionality;
  
  /** Whether to dispose overlay on navigation */
  disposeOnNavigation?: boolean;
}

/**
 * Configuration for updating overlay size
 */
interface OverlaySizeConfig {
  width?: number | string;
  height?: number | string;
  minWidth?: number | string;
  minHeight?: number | string;
  maxWidth?: number | string;
  maxHeight?: number | string;
}

Position Strategies

Different strategies for positioning overlays relative to trigger elements or globally.

/**
 * Builder for creating position strategies
 */
class OverlayPositionBuilder {
  /**
   * Create a global position strategy
   * @returns GlobalPositionStrategy for absolute positioning
   */
  global(): GlobalPositionStrategy;
  
  /**
   * Create a connected position strategy
   * @param origin - Element or point to connect to
   * @returns FlexibleConnectedPositionStrategy for relative positioning
   */
  connectedTo(
    origin: ElementRef | Element | Point & {width?: number; height?: number;}
  ): FlexibleConnectedPositionStrategy;
}

/**
 * Base class for position strategies
 */
abstract class PositionStrategy {
  /** Attach the strategy to an overlay reference */
  attach(overlayRef: OverlayRef): void;
  
  /** Apply the positioning */
  apply(): void;
  
  /** Detach the strategy */
  detach(): void;
  
  /** Dispose of the strategy */
  dispose(): void;
}

/**
 * Global positioning strategy for absolute positioning
 */
class GlobalPositionStrategy extends PositionStrategy {
  /** Set top position */
  top(value?: string): this;
  
  /** Set left position */
  left(value?: string): this;
  
  /** Set bottom position */
  bottom(value?: string): this;
  
  /** Set right position */
  right(value?: string): this;
  
  /** Set width */
  width(value?: string): this;
  
  /** Set height */
  height(value?: string): this;
  
  /** Center horizontally */
  centerHorizontally(offset?: string): this;
  
  /** Center vertically */
  centerVertically(offset?: string): this;
}

/**
 * Flexible connected positioning strategy for relative positioning
 */
class FlexibleConnectedPositionStrategy extends PositionStrategy {
  /**
   * Set the positions to try
   * @param positions - Array of position configurations
   */
  withPositions(positions: ConnectedPosition[]): this;
  
  /**
   * Whether to allow flexible dimensions
   * @param flexibleDimensions - Allow flexible sizing
   */
  withFlexibleDimensions(flexibleDimensions?: boolean): this;
  
  /**
   * Whether to push overlay on-screen if it would overflow
   * @param canPush - Allow pushing overlay
   */
  withPush(canPush?: boolean): this;
  
  /**
   * Whether to grow overlay after opening
   * @param growAfterOpen - Allow growing after open
   */
  withGrowAfterOpen(growAfterOpen?: boolean): this;
  
  /**
   * Set viewport margin
   * @param margin - Margin from viewport edge
   */
  withViewportMargin(margin: number): this;
  
  /**
   * Whether to lock position after opening
   * @param isLocked - Lock position
   */
  withLockedPosition(isLocked?: boolean): this;
  
  /**
   * Set the origin element
   * @param origin - New origin element or point
   */
  withOrigin(
    origin: ElementRef | Element | Point & {width?: number; height?: number;}
  ): this;
  
  /**
   * Set default X offset
   * @param offset - Default X offset
   */
  withDefaultOffsetX(offset: number): this;
  
  /**
   * Set default Y offset
   * @param offset - Default Y offset
   */
  withDefaultOffsetY(offset: number): this;
}

/**
 * Connected position configuration
 */
interface ConnectedPosition {
  /** Horizontal origin point */
  originX: 'start' | 'center' | 'end';
  
  /** Vertical origin point */
  originY: 'top' | 'center' | 'bottom';
  
  /** Horizontal overlay point */
  overlayX: 'start' | 'center' | 'end';
  
  /** Vertical overlay point */
  overlayY: 'top' | 'center' | 'bottom';
  
  /** Position weight for fallback ordering */
  weight?: number;
  
  /** X offset from origin */
  offsetX?: number;
  
  /** Y offset from origin */
  offsetY?: number;
  
  /** CSS classes for this position */
  panelClass?: string | string[];
}

Scroll Strategies

Strategies for handling scroll behavior when overlays are open.

/**
 * Available scroll strategies
 */
interface ScrollStrategyOptions {
  /** No-op scroll strategy (does nothing) */
  noop(): NoopScrollStrategy;
  
  /** Close overlay when scrolling */
  close(config?: CloseScrollStrategyConfig): CloseScrollStrategy;
  
  /** Block scrolling while overlay is open */
  block(): BlockScrollStrategy;
  
  /** Reposition overlay when scrolling */
  reposition(config?: RepositionScrollStrategyConfig): RepositionScrollStrategy;
}

/**
 * Base scroll strategy interface
 */
interface ScrollStrategy {
  /** Attach strategy to overlay reference */
  attach(overlayRef: OverlayRef): void;
  
  /** Enable the scroll strategy */
  enable(): void;
  
  /** Disable the scroll strategy */
  disable(): void;
  
  /** Detach the strategy */
  detach(): void;
}

/**
 * Configuration for close scroll strategy
 */
interface CloseScrollStrategyConfig {
  /** Threshold for closing */
  threshold?: number;
}

/**
 * Configuration for reposition scroll strategy
 */
interface RepositionScrollStrategyConfig {
  /** Scroll throttle in milliseconds */
  scrollThrottle?: number;
  
  /** Whether to auto-close on scroll */
  autoClose?: boolean;
}

Connected Overlay Directive

Directive for creating connected overlays declaratively.

/**
 * Directive for creating connected overlays
 */
@Directive({
  selector: '[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]'
})
class CdkConnectedOverlay implements OnDestroy {
  /** Origin element for positioning */
  @Input() cdkConnectedOverlayOrigin: CdkOverlayOrigin;
  
  /** Position configurations */
  @Input() cdkConnectedOverlayPositions: ConnectedPosition[];
  
  /** X offset */
  @Input() cdkConnectedOverlayOffsetX: number;
  
  /** Y offset */
  @Input() cdkConnectedOverlayOffsetY: number;
  
  /** Overlay width */
  @Input() cdkConnectedOverlayWidth: number | string;
  
  /** Overlay height */
  @Input() cdkConnectedOverlayHeight: number | string;
  
  /** Minimum width */
  @Input() cdkConnectedOverlayMinWidth: number | string;
  
  /** Minimum height */
  @Input() cdkConnectedOverlayMinHeight: number | string;
  
  /** Backdrop CSS classes */
  @Input() cdkConnectedOverlayBackdropClass: string | string[];
  
  /** Panel CSS classes */
  @Input() cdkConnectedOverlayPanelClass: string | string[];
  
  /** Whether overlay is open */
  @Input() cdkConnectedOverlayOpen: boolean;
  
  /** Whether to disable close on backdrop click */
  @Input() cdkConnectedOverlayDisableClose: boolean;
  
  /** Scroll strategy */
  @Input() cdkConnectedOverlayScrollStrategy: ScrollStrategy;
  
  /** Whether to show backdrop */
  @Input() cdkConnectedOverlayHasBackdrop: boolean;
  
  /** Whether to lock position */
  @Input() cdkConnectedOverlayLockPosition: boolean;
  
  /** Whether to allow flexible dimensions */
  @Input() cdkConnectedOverlayFlexibleDimensions: boolean;
  
  /** Whether to grow after opening */
  @Input() cdkConnectedOverlayGrowAfterOpen: boolean;
  
  /** Whether to push overlay on-screen */
  @Input() cdkConnectedOverlayPush: boolean;
  
  /** Backdrop click events */
  @Output() backdropClick: EventEmitter<MouseEvent>;
  
  /** Position change events */
  @Output() positionChange: EventEmitter<ConnectedOverlayPositionChange>;
  
  /** Attach events */
  @Output() attach: EventEmitter<void>;
  
  /** Detach events */
  @Output() detach: EventEmitter<void>;
  
  /** Overlay keydown events */
  @Output() overlayKeydown: EventEmitter<KeyboardEvent>;
  
  /** Outside click events */
  @Output() overlayOutsideClick: EventEmitter<MouseEvent>;
}

/**
 * Directive for marking overlay origin elements
 */
@Directive({
  selector: '[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]'
})
class CdkOverlayOrigin {
  /** The element reference */
  elementRef: ElementRef;
}

Overlay Container

Service for managing the container element that holds all overlays.

/**
 * Service for managing the overlay container
 */
class OverlayContainer {
  /**
   * Get the container element for overlays
   * @returns HTMLElement that contains all overlays
   */
  getContainerElement(): HTMLElement;
}

Types and Interfaces

/**
 * Point interface for positioning
 */
interface Point {
  x: number;
  y: number;
}

/**
 * Position change event for connected overlays
 */
interface ConnectedOverlayPositionChange {
  /** The position that was applied */
  connectionPair: ConnectedPosition;
  
  /** The scroll position */
  scrollableViewProperties: ScrollingVisibility;
}

/**
 * Scrolling visibility information
 */
interface ScrollingVisibility {
  isOriginClipped: boolean;
  isOriginOutsideView: boolean;
  isOverlayClipped: boolean;
  isOverlayOutsideView: boolean;
}

Usage Patterns

Creating a Simple Tooltip

import { Overlay, OverlayRef } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';

@Component({
  selector: 'app-tooltip-trigger',
  template: '<button (mouseenter)="showTooltip()" (mouseleave)="hideTooltip()">Hover me</button>'
})
export class TooltipTriggerComponent {
  private overlayRef: OverlayRef | null = null;

  constructor(private overlay: Overlay) {}

  showTooltip() {
    if (this.overlayRef) return;

    const positionStrategy = this.overlay.position()
      .flexibleConnectedTo(this.elementRef)
      .withPositions([
        {
          originX: 'center',
          originY: 'bottom',
          overlayX: 'center',
          overlayY: 'top',
          offsetY: 8
        }
      ]);

    this.overlayRef = this.overlay.create({
      positionStrategy,
      scrollStrategy: this.overlay.scrollStrategies.reposition(),
      hasBackdrop: false
    });

    const portal = new ComponentPortal(TooltipComponent);
    this.overlayRef.attach(portal);
  }

  hideTooltip() {
    if (this.overlayRef) {
      this.overlayRef.dispose();
      this.overlayRef = null;
    }
  }
}

Creating a Modal Dialog

import { Overlay, OverlayRef } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';

@Injectable()
export class DialogService {
  constructor(private overlay: Overlay) {}

  open<T>(component: ComponentType<T>, data?: any): OverlayRef {
    const overlayRef = this.overlay.create({
      hasBackdrop: true,
      backdropClass: 'dialog-backdrop',
      panelClass: 'dialog-panel',
      positionStrategy: this.overlay.position()
        .global()
        .centerHorizontally()
        .centerVertically(),
      scrollStrategy: this.overlay.scrollStrategies.block()
    });

    const portal = new ComponentPortal(component);
    const componentRef = overlayRef.attach(portal);

    // Pass data to component
    if (data) {
      Object.assign(componentRef.instance, data);
    }

    // Close on backdrop click
    overlayRef.backdropClick().subscribe(() => {
      overlayRef.dispose();
    });

    return overlayRef;
  }
}