MD3
Expressive
MATERIAL DESIGN 3 EXPRESSIVE

Icons

Material Symbols Variable Font integration with customizable axes and hardware-accelerated animations.

The <Icon /> component provides a highly performant wrapper around Google's Material Symbols variable font. Instead of shipping static SVG files, it leverages a single variable font file capable of infinite interpolation across 4 distinct typography axes.

Introduction

Material Symbols are the next generation of Material Icons, designed to be more flexible and expressive. By using a variable font, the <Icon /> component can morph between different weights, fills, and styles without loading multiple assets. This ensures faster load times and smoother animations, especially for state transitions like "liking" or "favoriting" an item.

Anatomy

  • Glyph: The visual representation of the icon, defined by its name (ligature).
  • Axes: Four parameters (Fill, Weight, Grade, Optical Size) that control the font's geometry.
  • Bounding Box: The 24x24dp (default) area that contains the icon, ensuring consistent alignment with other UI elements.

Variants

Stylistic Variants

Material Symbols offers three distinct stylistic variations, each providing a different aesthetic for your application:

  • Outlined (Default): Modern, clean lines.
  • Rounded: Softer, friendlier geometric forms.
  • Sharp: Direct, high-precision geometry.
Loading demo...

Features

Variable Font Axes

The <Icon /> component exposes four axes for fine-tuned control:

  • Fill: Toggle between outlined (0) and solid (1) styles.
  • Weight: Adjust the thickness of the icon strokes (100–700).
  • Grade: Fine-tune the stroke weight without affecting the icon's dimensions (-50 to 200).
  • Optical Size: Optimize the icon's rendering for specific display sizes (20, 24, 40, 48).
Loading demo...

Expressive Animations

By setting animateFill={true}, the icon can smoothly transition between its outlined and filled states. This is powered by motion/react and provides a premium feel to interactive icons.

Loading demo...

Usage

Basic Usage

import { Icon } from "@bug-on/m3-expressive";

<Icon name="favorite" />

Advanced Customization

<Icon 
  name="settings" 
  weight={600} 
  fill={1} 
  grade={100} 
  opticalSize={48} 
/>

Animated Toggle

const [isFavorite, setIsFavorite] = useState(false);

<Icon 
  name="favorite" 
  fill={isFavorite ? 1 : 0} 
  animateFill 
  onClick={() => setIsFavorite(!isFavorite)}
/>

Best Practices

Do

  • Use consistent icon styles (e.g., all Rounded) throughout your application.
  • Use Optical Size that matches the icon's actual display size for the clearest rendering.
  • Animate the Fill axis for toggle actions like "Like" or "Bookmark" for better feedback.
  • Pair icons with text labels or tooltips to ensure their meaning is clear.

Don't

  • Don't use different stylistic variants (e.g., Outlined and Sharp) on the same screen.
  • Avoid using very light weights (100) on low-contrast backgrounds as they may be hard to see.
  • Don't use complex icons at small sizes where they may lose detail.

Accessibility

  • Decorative Icons: By default, icons are marked with aria-hidden="true" as they are usually decorative.
  • Semantic Icons: If an icon conveys meaning on its own, wrap it in an IconButton or provide an aria-label on a parent element.
  • Contrast: Ensure the icon color meets WCAG contrast requirements against its background.

API Reference

Icon

PropTypeDefaultDescription
namestringRequired. Ligature name (e.g., "search").
variant"outlined" | "rounded" | "sharp""outlined"Stylistic variation.
fillnumber0Fill level (0 to 1).
weightnumber400Stroke thickness (100-700).
gradenumber0Emphasis modifier (-50 to 200).
opticalSizenumber24Rendering optimization size.
sizenumber24Visual font-size in pixels.
animateFillbooleanfalseEnables spring animation for fill changes.
classNamestringCustom classes.