MD3
Expressive
MATERIAL DESIGN 3 EXPRESSIVE

Chips

Chips help people enter information, make selections, filter content, or trigger actions.

Chips are compact interactive elements that represent an input, attribute, or action. They allow users to enter information, make selections, filter content, or trigger secondary actions.

Introduction

The MD3 Expressive Chips are designed to be compact and highly functional. They adapt their appearance and behavior based on their purpose: assisting with actions, filtering content, providing input entities, or offering suggestions. Each variant features smooth transitions and tactile feedback through MD3 Ripple and elevation animations.

Anatomy

  • Container: A rounded surface that holds the content.
  • Leading Icon / Avatar (Optional): A visual indicator or entity representation at the start.
  • Label: The descriptive text for the chip.
  • Trailing Icon / Remove Button (Optional): Typically used for dismissing or removing input chips.
  • State Layer: Handles hover and pressed states with a ripple effect.

Variants

Assist Chips

Assist chips represent contextual actions that help a user complete a task. They can be flat or elevated.

Loading demo...

Filter Chips

Filter chips allow users to toggle filters for content. They show a checkmark animation when selected.

Loading demo...

Input Chips

Input chips represent complex information, such as a person or a tag, in a compact form. They often include a "remove" button.

Loading demo...

Suggestion Chips

Suggestion chips provide dynamic hints or answers based on the current context, helping users move forward in their journey.

Loading demo...

Features

Elevation

Certain chip variants (Assist, Filter, Suggestion) support an elevated style, which uses shadow to create depth and separation from the background.

Selection States

Filter and Input chips support a selected state, which changes their background color and adds a checkmark (for Filter chips).

Loading demo...

Usage

Basic Usage

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

<Chip label="Add to calendar" variant="assist" icon={<Icon name="event" />} />

Filter Selection

const [selected, setSelected] = useState(false);

<Chip 
  label="Photos" 
  variant="filter" 
  selected={selected} 
  onClick={() => setSelected(!selected)} 
/>

Removable Input Chip

<Chip 
  label="John Doe" 
  variant="input" 
  avatar={<Avatar src="/john.jpg" />} 
  onRemove={() => handleRemove()} 
/>

Next.js Integration (asChild)

Use asChild to render a Chip as a Next.js Link for tag/category navigation.

import Link from "next/link";
import { Chip } from "@bug-on/m3-expressive";

<Chip asChild label="React">
  <Link href="/tags/react">React</Link>
</Chip>

Best Practices

Do

  • Use chips for categorical selection or filtering.
  • Keep labels short (1-2 words).
  • Use input chips for representing entities like people or tags in a text field.
  • Group related chips together in a horizontal list (Chip Set).

Don't

  • Don't use chips as the primary navigation for a site (use Tabs or a Rail instead).
  • Don't use a chip if a standard Button would be more appropriate for a primary action.
  • Avoid putting too many chips in a small area; allow for horizontal scrolling if necessary.

Accessibility

  • Keyboard: Full support for Tab to focus and Enter/Space to trigger.
  • Roles: Automatically applies appropriate roles like button or checkbox based on variant.
  • States: Selected chips use aria-pressed or aria-checked.
  • Remove Action: The remove button is a separate tab stop with its own aria-label.

API Reference

Chip

PropTypeDefaultDescription
variant"assist" | "filter" | "input" | "suggestion""assist"Behavioral variant.
labelReactNodeRequired. Chip text.
elevatedbooleanfalseEnables elevated style.
selectedbooleanfalseActive/Selected state.
disabledbooleanfalseDisables interaction.
leadingIconReactNodeIcon at the start.
avatarReactNodeAvatar image/component.
onRemove() => voidCallback for the "×" button.
asChildbooleanfalseRenders as the child element (e.g., Next.js Link) while keeping styles.
onClick() => voidClick handler.
classNamestringCustom classes.