Chip
Tag that can be selectable, removable or used as a filter.
Installation
npx axiom add chippnpm dlx axiom add chipyarn dlx axiom add chipbun x axiom add chipAlso copies: tappable.
Requires the close icon in your icon registry. Colors come from chip.{outline,filled}.{default,pressed,selected,disabled} in the component tokens.
Usage
import { Chip } from '@/components/ui/chip';
<Chip selected={onlyUnread} onPress={toggleUnread}>Unread</Chip>
<Chip onRemove={() => removeTag('travel')}>Travel</Chip>Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | The label. |
selected | boolean | — | Selected state, drawn with the inverse colors. Setting it makes the chip a toggle (accessibilityRole="togglebutton"). |
onPress | () => void | — | Called when the chip is pressed. Usually toggles selected or opens a picker. |
onRemove | () => void | — | Shows a close icon on the right. Pressing it calls onRemove; the icon has its own 44pt touch area. |
variant | 'outline' | 'filled' | 'outline' | outline for filters, filled for tags and entered values. |
size | 'sm' | 'md' | 'md' | Minimum height: 28 or 34pt. Grows with larger system text. The touch area stays 44pt. |
leading | IconName | ReactNode | — | Icon or Avatar before the label. |
trailing | IconName | ReactNode | — | Icon after the label, like a chevron for a chip that opens a menu. Ignored with onRemove. |
disabled | boolean | false | Blocks presses and dims the chip. |
accessibilityLabel | string | label text | Override when the label alone is unclear. The remove button is announced as "Remove <label>". |
style | StyleProp<ViewStyle> | — | Extra styles for the chip. |
Chip.Group
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Chip elements. |
layout | 'wrap' | 'scroll' | 'wrap' | wrap flows onto several lines, scroll keeps one horizontal line that scrolls with screen margins. |
gap | SpacingToken | 2 | Space between chips. |
Use cases
Filter bar under a search
A horizontal Chip.Group layout="scroll". Each chip toggles one filter; the list updates right away.
<Chip.Group layout="scroll">
{filters.map((f) => (
<Chip
key={f.id}
size="sm"
selected={active.has(f.id)}
onPress={() => toggle(f.id)}
>
{f.label}
</Chip>
))}
</Chip.Group>Tags entered by the user
Each value becomes a removable chip next to the input.
<Chip.Group>
{tags.map((t) => (
<Chip key={t} variant="filled" size="sm" onRemove={() => removeTag(t)}>
{t}
</Chip>
))}
</Chip.Group>Filter that opens a picker
A chevron and a value in the label: the chip opens a BottomSheet instead of toggling.
<Chip selected={price != null} trailing="chevron-down" onPress={openPriceSheet}>
{price ? `Price: ${price}` : "Price"}
</Chip>