Chip
A compact token: a tag, a filter, a status, an entity plucked out of a list.
import { Chip } from 'neba';
<Chip>design-system</Chip>
<Chip color="danger" count={12}>Errors</Chip>
<Chip onDelete={remove}>typescript</Chip>;Props
| Prop | Type | Default | Description |
|---|---|---|---|
| variantshared | 'solid' | 'outline' | 'text' | 'outline' | Weight of the surface: filled, hairline, or none |
| sizeshared | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Height and type scale, one step below the control of the same size — a md chip is a sm control |
| colorshared | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'primary' | Semantic colour role. Arbitrary colour values are not accepted |
| densityshared | 'default' | 'compact' | 'default' | Padding only — never the height, never the type scale |
| elevationshared | 0 | 1 | 2 | 3 | 0 | Drop shadow depth. A chip sits on something else, so this is rarely raised |
| startIcon | ReactNode | — | Content before the label — an icon, a status dot, an avatar |
| endIcon | ReactNode | — | Content after the label, before any count |
| count | ReactNode | — | A number set into the end, on its own small plate |
| onClick | (event) => void | — | Passing it turns the label into a real button |
| onDelete | (event) => void | — | Passing it adds the delete button — its own button, separate from onClick |
| deleteLabel | string | 'Remove' | Accessible name of the delete button |
| selected | boolean | false | Chosen. Deepens the surface a step rather than changing the colour family |
| disabled | boolean | false | Unavailable |
| children | ReactNode | — | The chip's label |
Examples
Variants and colours
Icons and counts
A count gets its own small plate, so "Errors 12" reads as one token with a number on it rather than as two words. On a filled chip the plate is a hole punched in the fill; on a tinted or bare one it is the accent showing through.
Clickable and deletable
selected deepens the surface one step rather than changing the colour family — a filter that is on is still the same filter.
Sizes
A chip is one step down the ladder
A md chip is a sm control — 26px, not 32px. That is the whole visual difference between a Chip and a Button, and it is deliberate: a chip is a token inside a row of content, not a control the row lines up against. At full control height an outline chip and an outline button are the same object, and a screen full of them says nothing about which one can be pressed.
Every other library reaches for a pill radius to make that distinction, which this one cannot — the flat run along a sheet's top and bottom edge is the point of the whole design language.
Accessibility
The shell is always a <span>. What changes is what is inside it: a plain run of content, or — when onClick is given — a real <button> wrapping that content, plus a second button for onDelete.
Both are reachable by keyboard and neither is nested inside the other. An inert <span> carrying a click handler is the most common way a component library loses its keyboard users; a <button> inside a <button> is the most common way it invents markup the browser silently rewrites. This shape avoids both.
Give the delete button a deleteLabel naming what is being removed when there is more than one chip on screen.