Chip
Compact tag with an optional dense remove button.
import { Chip } from '@elirobinson/react/components/molecules/Chip';Styles: @elirobinson/react/styles/molecules/Chip.css — already included when you import @elirobinson/react/styles.css.
CoachingRecipesAI consulting
Show code
import { Chip } from '@elirobinson/react/components/molecules/Chip';
export default function Basic() {
return (
<div className="demo-row">
<Chip>Coaching</Chip>
<Chip>Recipes</Chip>
<Chip>AI consulting</Chip>
</div>
);
}When to use it
Use Chip for a compact, removable tag — an active filter, a selected item in a
multi-select field, a keyword attached to a piece of content. Without onRemove it's
just a static tag; with it, a small × button appears. For a status label that's never
removable, Badge is the simpler component.
Removable
Pass onRemove to get the dense remove button. It's sized to the shadcn/MUI scale, not
the 44px primary-control minimum — a chip is an inline, dense affordance, not a button.
Practice plansU10SoccerFall season
Show code
import { useState } from 'react';
import { Chip } from '@elirobinson/react/components/molecules/Chip';
export default function Removable() {
const [tags, setTags] = useState(['Practice plans', 'U10', 'Soccer', 'Fall season']);
const removeTag = (tag: string) => {
setTags((current) => current.filter((item) => item !== tag));
};
return (
<div className="demo-row">
{tags.length === 0 ? (
<p>No filters applied.</p>
) : (
tags.map((tag) => (
<Chip key={tag} onRemove={() => removeTag(tag)}>
{tag}
</Chip>
))
)}
</div>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
onRemove | (() => void) | — | — |
removeLabel | string | — | Accessible name for the remove button. Defaults to `Remove ${children}`, which only produces a correct label when `children` is a plain string. Pass this explicitly when `children` is an element (e.g. `<b>Design</b>`). |
Also accepts all HTMLAttributes<HTMLSpanElement> props.
Accessibility
- Renders a
<span>wrapper around a label span and, whenonRemoveis passed, a native<button type="button">for removal — everything else about the chip is non-interactive. - The remove button's accessible name defaults to
`Remove ${children}`. That only produces a correct label whenchildrenis a plain string — passremoveLabelexplicitly when the content is an element (<b>Design</b>would otherwise stringify wrong). - The remove button follows dense inline sizing (MUI/shadcn scale), not the 44px primary-control minimum, since a chip's own footprint is already small.
- Keyboard: the remove button is a native
<button>—Tabreaches it,EnterandSpaceactivate it. The chip body itself isn't focusable. - The ref forwards to the outer
<span>.
Do
- Keep chip labels to a word or short phrase — a filter name, a tag, a selected value.
- Pass removeLabel when the chip content is anything other than plain text.
- Update surrounding state (a filter list, a form value) synchronously in onRemove.
- Use Chip for values the user actively chose and can un-choose.
Don't
- Use Chip for a status that isn't removable — that's Badge.
- Rely on the expanded hit area overlapping the label — the remove button's target is bounded to its own footprint.
- Put more than a handful of chips in a row without wrapping — it turns into a wall of tags.
- Make the whole chip clickable for one action and removable for another; keep each chip to a single control.