Skip to main content
Mat Expressive

Icon Button

Import Statement
import { MatExpIconButton } from '@ngm-dev/mat-exp';

Pre-requisites

Make sure either you have included mat-exp-all-styles, mat-exp-all-buttons-styles or mat-exp-icon-button-styles in your global SCSS styles.

SCSS
@use '@ngm-dev/mat-exp' as mat-exp;

html {
  @include mat-exp.mat-exp-all-styles();
}

or

SCSS
@use '@ngm-dev/mat-exp' as mat-exp;

html {
  @include mat-exp.mat-exp-all-buttons-styles();
}

or

SCSS
@use '@ngm-dev/mat-exp' as mat-exp;

html {
  @include mat-exp.mat-exp-icon-button-styles();
}

Usage

The styles for Material Expressive Button can be applied in two ways:

  1. Using the .mat-exp-icon-button class with the data-* attributes
  2. Using the matExpIconButton directive

Using the .mat-exp-icon-button class with the data-\* attributes

app.ts
import { MatIconButton } from '@angular/material/button';
import { MatIcon } from '@angular/material/icon';
@Component({
  selector: 'app-root',
  imports: [MatIconButton, MatIcon],
  template: `
    <button mat-icon-button class="mat-exp-icon-button" data-size="xs" data-shape="square">
      <mat-icon>home</mat-icon>
    </button>
    <button mat-icon-button class="mat-exp-icon-button" data-size="sm">
      <mat-icon>home</mat-icon>
    </button>
  `,
})
export class App {}

Using the matExpIconButton directive

If you do not want to use data-* attributes and the .mat-exp-icon-button class and want full type safety, you can use matExpIconButton directive.

app.ts
import { MatExpIconButton } from '@ngm-dev/mat-exp';
import { MatIcon } from '@angular/material/icon';
@Component({
  selector: 'app-root',
  imports: [MatIconButton, MatExpIconButton, MatIcon],
  template: `
    <button mat-icon-button size="xs" shape="square" matExpIconButton>
      <mat-icon>home</mat-icon>
    </button>
    <button mat-icon-button size="sm" matExpIconButton>
      <mat-icon>home</mat-icon>
    </button>
  `,
})
export class App {}

Supported Variations

Mat Expressive Icon Button supports the following variations:

  • Size: xs, s, m, l, xl
  • Shape: round, square
  • Toggle: selected, unselected
  • State: pressed (:active pseudo-selector)
  • Appearance: text, outlined, filled, tonal
  • Width: default, narrow, wide

Toggle Behavior

Mat Expressive Icon Button supports a toggle state (selected / unselected), but toggling on click is only automatic inside a <mat-exp-button-group> — the group owns selection state for every button it manages.

Standalone toggle buttons (outside a <mat-exp-button-group>) do not flip toggle on click. This is intentional: a lone button's click handler only has one consumer to satisfy, so the library leaves the state transition up to you rather than guessing what a click should mean. Two-way bind toggle and flip it yourself in your own (click) handler:

app.ts
import { signal } from '@angular/core';
import { MatIconButton } from '@angular/material/button';
import { MatIcon } from '@angular/material/icon';
import { MatExpIconButton } from '@ngm-dev/mat-exp';

@Component({
  selector: 'app-root',
  imports: [MatIconButton, MatExpIconButton, MatIcon],
  template: `
    <button
      mat-icon-button
      matExpIconButton
      [(toggle)]="favorited"
      (click)="favorited.set(favorited() === 'selected' ? 'unselected' : 'selected')"
    >
      <mat-icon>favorite</mat-icon>
    </button>
  `,
})
export class App {
  protected readonly favorited = model<'selected' | 'unselected'>('unselected');
}

Inside a MatExpButtonGroup, don't do this — the group already manages toggle for its projected buttons based on the group's single-/multi-select state, and a manual click handler would fight the group's own state management.

Accessibility

The shape-morph transition (border-radius, padding-left/padding-right, box-shadow) automatically stops under prefers-reduced-motion: reduce — Angular Material's own matIconButton host, which matExpIconButton is always applied alongside, detects the setting and neutralizes the transition. See Reduced Motion for how this works across the library.

Playground

API

Data Attributes with .mat-exp-icon-button class

Use these data-* attributes with the .mat-exp-icon-button class to style the Angular Material Icon Button component:

Attribute Default Possible values
data-size s xs, s, m, l, xl
data-shape round round, square
data-toggle unselected selected, unselected
data-appearance text text, outlined, filled, tonal
data-width default default, narrow, wide

`MatExpIconButton`

Standalone directive, selector [matExpIconButton], exported as matExpIconButton.

You can view the generated API for MatExpIconButton here.

Host

Attribute / binding Value
data-size From size() input
data-shape From shape() input
data-appearance From appearance input
data-toggle From toggle() input
data-width From width() input
data-menu-open true when a [matMenuTriggerFor] on the same host has its menu open
aria-pressed 'true' / 'false' derived from toggle(); omitted entirely when toggle() is undefined
class mat-exp-icon-button
(click) Delegates the click to the parent MatExpButtonGroup, if any

Inputs

Input Type Default Description
size MatExpButtonSize 's' Size of the icon button.
shape MatExpButtonShape 'round' Shape of the icon button.
width MatExpIconButtonWidth 'default' Width of the icon button.
toggle MatExpButtonToggle | undefined undefined Toggle state. Only auto-managed inside a MatExpButtonGroup — see Toggle Behavior above.
value unknown undefined Value read by a parent MatExpButtonGroup when computing its own form value.
appearance MatExpIconButtonAppearance | undefined 'text' Appearance of the icon button.

size, shape, toggle, and value are declared with model() (two-way bindable, e.g. [(size)]="mySize"); width uses input(); appearance is a classic @Input() accessor.

Types:

  • MatExpButtonSize'xs' | 's' | 'm' | 'l' | 'xl'
  • MatExpButtonShape'round' | 'square'
  • MatExpButtonToggle'selected' | 'unselected'
  • MatExpIconButtonWidth'default' | 'narrow' | 'wide'
  • MatExpIconButtonAppearance'text' | 'filled' | 'outlined' | 'tonal'

Note

MatExpIconButton also exposes a plain disabled accessor that reads and writes the underlying Angular Material matIconButton directive's own disabled input directly — bind it through matIconButton as usual (e.g. [disabled]).


Options and provider

`MatExpIconButtonOptions`

TypeScript
interface MatExpIconButtonOptions {
  readonly appearance?: MatExpIconButtonAppearance;
  readonly size?: MatExpButtonSize;
  readonly shape?: MatExpButtonShape;
  readonly toggle?: MatExpButtonToggle;
  readonly width?: MatExpIconButtonWidth;
}

`MAT_EXP_ICON_BUTTON_DEFAULT_OPTIONS`

Default object used when no provider overrides values:

  • size: 's'
  • shape: 'round'
  • width: 'default'
  • appearance: 'text'

`MAT_EXP_ICON_BUTTON_OPTIONS`

InjectionToken for the resolved options object; used internally by the directive.

`provideMatExpIconButtonOptions`

Angular TS
import { provideMatExpIconButtonOptions } from '@ngm-dev/mat-exp';

export const appConfig: ApplicationConfig = {
  providers: [
    provideMatExpIconButtonOptions({
      size: 'm',
      appearance: 'filled',
    }),
  ],
};

You may pass a partial static object or a factory () => Partial<MatExpIconButtonOptions>.

Styling

Usage

SCSS
@use '@ngm-dev/mat-exp' as mat-exp;

html {
  @include mat-exp.mat-exp-icon-button-styles($options);
}

Options

Option Type Default Description
skip-html-element-styles boolean false If true, the mixin won't apply styles to the underlying HTML elements.
sizes list of 'xs' | 's' | 'm' | 'l' | 'xl' null (all sizes emitted) Restricts the emitted CSS to only the given sizes. See Reducing the CSS Payload.
appearances list of 'text' | 'filled' | 'outlined' | 'tonal' null (all appearances emitted) Restricts the emitted CSS to only the given appearances.

`skip-html-element-styles`

Setting this to true means the following won't work as expected:

  • Icon sizes
  • Shape morphing
  • Appearance and width variations
SCSS
@use '@ngm-dev/mat-exp' as mat-exp;

html {
  @include mat-exp.mat-exp-icon-button-styles(
    (
      skip-html-element-styles: true,
    )
  );
}

`sizes`

Drops the rest of the size combination matrix at compile time.

SCSS
@use '@ngm-dev/mat-exp' as mat-exp;

html {
  @include mat-exp.mat-exp-icon-button-styles(
    (
      sizes: ('s', 'm'),
    )
  );
}

`appearances`

Drops the rest of the appearance combination matrix at compile time.

SCSS
@use '@ngm-dev/mat-exp' as mat-exp;

html {
  @include mat-exp.mat-exp-icon-button-styles(
    (
      appearances: ('filled'),
    )
  );
}