Angular Component Development Kit

https://briebug.github.io/presentations/ng-meetup/2017/10/angular-cdk/
Adam Armour
https://github.com/aarmour

@angular/cdk

https://github.com/angular/material2/tree/master/src/cdk
“The goal of the CDK is to give developers more tools to build awesome components for the web. This will be especially useful for projects that want to take advantage of the features of Angular Material without adopting the Material Design visual language.”

—  Angular Team

Portal and PortalHost

A Portal is a piece of UI that can be dynamically rendered to an open slot on the page…

where the piece of UI can be either a Component or a TemplateRef

and the open slot is a PortalHost.

Material Design

  • Tabs
  • Dialog
  • Snackbar

Example

Overlay

Mechanism for creating floating panels on the screen.

Position strategies:

GlobalPositionStrategy: for a specific position in the viewport (modal dialog, snackbar).

ConnectedPositionStrategy: position relative to an anchor (menu, tooltip).

PositionStrategy interface: implement for custom strategies.

Scroll strategies:

NoopScrollStrategy (default): does nothing.

CloseScrollStrategy: close the overlay on scroll.

BlockScrollStrategy: prevent scrolling when the overlay is open.

RepositionScrollStrategy: reposition the overlay element on scroll. (May impact performance).

ScrollStrategy interface: implement for custom strategies.

Table

The <cdk-table> is an unopinionated, customizable data-table with a fully-templated API, dynamic columns, and an accessible DOM structure.


<cdk-table #table [dataSource]="dataSource">

  <!-- ID Column -->
  <ng-container cdkColumnDef="userId">
    <cdk-header-cell *cdkHeaderCellDef>
      ID
    </cdk-header-cell>
    <cdk-cell *cdkCellDef="let row">
      {{row.id}}
    </cdk-cell>
  </ng-container>

  <!-- Name Column -->
  <ng-container cdkColumnDef="userName">
    <cdk-header-cell *cdkHeaderCellDef>
      Name
    </cdk-header-cell>
    <cdk-cell *cdkCellDef="let row">
      {{row.name}}
    </cdk-cell>
  </ng-container>

  <cdk-header-row *cdkHeaderRowDef="displayedColumns"></cdk-header-row>
  <cdk-row *cdkRowDef="let row; columns: displayedColumns;"></cdk-row>
</cdk-table>
          

Define the columns


<ng-container cdkColumnDef="username">
  <cdk-header-cell *cdkHeaderCellDef>
    User name
  </cdk-header-cell>
  <cdk-cell *cdkCellDef="let row">
    {{row.a}}
  </cdk-cell>
</ng-container>
          

Define the header and data rows


<cdk-header-row
  *cdkHeaderRowDef="['username', 'age', 'title']">
</cdk-header-row>
<cdk-row
  *cdkRowDef="let row; columns: ['username', 'age', 'title']">
</cdk-row>
          

Stepper

  • Manages which step is active.
  • Handles keyboard interaction.
  • Provides an API for advancing or rewinding the workflow.

Supports two approaches:

  1. Using a single form for the entire stepper.
  2. Using a form for each individual step.

Accessibility

ListKeyManager

Manages the active option in a list of items based on keyboard interaction.

Two types:

FocusKeyManager: for options that directly receive focus.

ActiveDescendentKeyManager: for options that use aria-activedescendant.

Any component that uses a ListKeyManager will generally do three things:

  • Create a @ViewChildren query for the options being managed.
  • Initialize the ListKeyManager, passing in the options.
  • Forward keyboard events from the managed component to the ListKeyManager.

FocusTrap

cdkFocusTrap directive keeps focus within an element.


<div class="dialog-content" cdkTrapFocus>
  <!-- Tab and Shift + Tab will not leave this element. -->
</div>
          

Layout: BreakpointObserver

Utility for evaluating media queries and reacting to changes.

Bidirectionality

Directionality

Service that provides the current direction value ('ltr' or 'rtl') and a stream for observing changes to direction.


@Component()
class DirectionalityExample {
  private isRtl: boolean;
  private dirChangeSubscription = Subscription.EMPTY;
  
  constructor(dir: Directionality) {
    this.isRtl = dir.value === 'rtl';
  
    dirChangeSubscription = dir.change.subscribe(() => {
      // Direction has changed
    });
  }
}
          

Scrolling

cdkScrollable and ScrollDispatcher

React to scrolling in any ancestor scrolling containers.

Example

References