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.
Filter Chips
Filter chips allow users to toggle filters for content. They show a checkmark animation when selected.
Input Chips
Input chips represent complex information, such as a person or a tag, in a compact form. They often include a "remove" button.
Suggestion Chips
Suggestion chips provide dynamic hints or answers based on the current context, helping users move forward in their journey.
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).
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
Tabto focus andEnter/Spaceto trigger. - Roles: Automatically applies appropriate roles like
buttonorcheckboxbased on variant. - States: Selected chips use
aria-pressedoraria-checked. - Remove Action: The remove button is a separate tab stop with its own
aria-label.
API Reference
Chip
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "assist" | "filter" | "input" | "suggestion" | "assist" | Behavioral variant. |
label | ReactNode | — | Required. Chip text. |
elevated | boolean | false | Enables elevated style. |
selected | boolean | false | Active/Selected state. |
disabled | boolean | false | Disables interaction. |
leadingIcon | ReactNode | — | Icon at the start. |
avatar | ReactNode | — | Avatar image/component. |
onRemove | () => void | — | Callback for the "×" button. |
asChild | boolean | false | Renders as the child element (e.g., Next.js Link) while keeping styles. |
onClick | () => void | — | Click handler. |
className | string | — | Custom classes. |