Angular 22

Angular Material 22

New features in @angular/material@22 , button progress indicators, dialog input bindings, flexible tab animations, stabilized ARIA components, and more.

1. Button Progress Indicator

Buttons now accept a [showProgress] input that displays a built-in spinner overlay. No extra wrapper or positioning needed.

Click any button , it shows a progress spinner for 2 seconds.

// Button with built-in progress indicator (Angular Material 22)
<button mat-flat-button [showProgress]="loading()">
  Submit
</button>

// In the component:
loading = signal(false);

submit() {
  this.loading.set(true);
  await saveData();
  this.loading.set(false);
}

2. Dialog with Input Bindings

MatDialog.open() now supports a bindings array. Pass inputBinding() from @angular/core to bind signal values directly to the dialog component's input() signals , no MAT_DIALOG_DATA injection needed.

// Open a dialog with reactive input bindings (no data bag!)
import { inputBinding } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';

dialog = inject(MatDialog);
userName = signal('World');

openDialog() {
  this.dialog.open(GreetingDialog, {
    bindings: [
      inputBinding('name', () => this.userName()),
      inputBinding('color', () => '#e11d48'),
    ],
  });
}

// The dialog component uses input() signals:
@Component({ ... })
export class GreetingDialog {
  name = input('World');
  color = input('#6366f1');
}

3. Tab Animation Durations

[animationDuration] now accepts an object with separate body and header durations, giving finer control over tab transitions.

Overview content , switch tabs to see the animation difference.

// Uniform duration (string)
<mat-tab-group animationDuration="500ms">

// Separate body/header durations (new in Material 22)
<mat-tab-group [animationDuration]="{ body: '800ms', header: '200ms' }">

// Type: MatTabGroupAnimationDuration = string | number | {
//   body: string | number;
//   header: string | number;
// }

4. CDK ARIA Components Stabilized

Seven CDK ARIA primitives moved from cdk-experimental to stable in v22. These are low-level building blocks for custom accessible widgets.

  • CdkCombobox , autocomplete / dropdown patterns
  • CdkGrid , data grid keyboard navigation
  • CdkListbox , single & multi-select listbox
  • CdkMenu , accessible menus & menu bars
  • CdkTabs , tab widget pattern
  • CdkToolbar , roving tabindex toolbar
  • CdkTree , treeview navigation
// Stabilized CDK ARIA components in v22:
// CdkCombobox, CdkGrid, CdkListbox, CdkMenu, CdkTabs, CdkToolbar, CdkTree

// Example: Using a CdkCombobox test harness
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { CdkComboboxHarness } from '@angular/cdk-experimental/combobox/testing';

let loader: HarnessLoader;
loader = TestbedHarnessEnvironment.loader(fixture);

const combobox = await loader.getHarness(CdkComboboxHarness);
await combobox.open();
expect(await combobox.isOpen()).toBeTrue();

5. CDK Portal Directives & Typography Mixins

ComponentPortal now supports attaching directives (not just components). New SCSS typography mixins give per-component control.

Portal Directives

Previously, ComponentPortal only accepted component types. In v22, you can attach a directive to a portal outlet , useful for injecting behaviour without rendering a host element.

// ComponentPortal now supports directives (v22)
import { ComponentPortal } from '@angular/cdk/portal';

// Previously: ComponentPortal only accepted components
// Now: you can attach directives too
const portal = new ComponentPortal(MyDirective);
portalOutlet.attach(portal);

Typography Mixins

New granular SCSS mixins let you apply Material typography to individual components instead of the entire app. Pair with define-theme() to customise type scales.

// New typography SCSS mixins (v22)
@use '@angular/material' as mat;

// Apply typography to all Material components
@include mat.typography(mat.$violet-theme);

// Apply to a specific component
@include mat.button-typography(mat.$violet-theme);

// Override specific type levels
$custom-theme: mat.define-theme((
  typography: (
    headline-small: mat.define-typeface(
      'Roboto', 400, 24px, 32px
    ),
  ),
));

6. Combobox Promoted to Stable

SimpleCombobox has been promoted to Combobox and moved from cdk-experimental to @angular/cdk. The legacy combobox and autocomplete implementations have been removed.

BeforeCdkSimpleCombobox from cdk-experimental
AfterCdkCombobox from @angular/cdk/combobox
// BEFORE (Angular ≤21) ,  SimpleCombobox (developer preview)
import { CdkSimpleCombobox } from '@angular/cdk-experimental/combobox';
<cdk-simple-combobox [values]="options">

// AFTER (Angular 22) ,  Combobox (stable!)
import { CdkCombobox } from '@angular/cdk/combobox';
<cdk-combobox [value]="selectedOption">

// Key renames:
// SimpleCombobox      → Combobox
// simple-combobox     → combobox (selector)
// [values]            → [value] (input)
// Legacy combobox and autocomplete are REMOVED

7. Google Maps: gmp-click Event

The Google Maps component now supports the gmp-click event for advanced marker interactions, providing richer event data including the exact LatLng of the click.

// Google Maps: gmp-click event support (Angular 22)
<google-map [center]="center" [zoom]="14">
  <map-advanced-marker
    [position]="markerPos"
    (gmpClick)="onMarkerClick($event)"
  />
</google-map>

// The gmp-click event provides richer data than the legacy
// click event, including the LatLng of the click point.

8. Material & CDK Breaking Changes

  • [values] → [value] — Renamed across Combobox, Listbox, Tree, Menu, Toolbar, and Select.
  • MatListOption.checkboxPosition — Removed. Use togglePosition instead.
  • ArrowViewState — Removed from MatSort.
  • ContextMenuTracker — Renamed to MenuTracker.
  • CDK Focus Trap — injector parameter now required. FocusTrapFactory.create(bool) replaced with config object.
  • DropListRef.drop(event) — event parameter is now required.
  • Rest-arg constructors removed — Update super() calls if extending Material/CDK classes.
// CDK Breaking Changes
CDK_DESCRIBEDBY_HOST_ATTRIBUTE     → removed
CDK_DESCRIBEDBY_ID_PREFIX          → removed
MESSAGES_CONTAINER_ID              → removed
ConfigurableFocusTrap(injector)    → injector now required
FocusTrapFactory.create(bool)      → create(config object)
DropListRef.drop(event)            → event now required
ContextMenuTracker                 → MenuTracker

// Material Breaking Changes
MatListOption.checkboxPosition     → togglePosition
MatListOptionCheckboxPosition      → MatListOptionTogglePosition
ArrowViewState (MatSort)           → removed
ArrowViewStateTransition (MatSort) → removed

// Renamed across all ARIA components
[values] input/model               → [value]
  (in Combobox, Listbox, Tree, Menu, Toolbar, Select)

// Constructors with rest args     → removed
  (update super() calls if extending Material/CDK components)