Chip
Chip is a compact inline label used for filters, entered values, and short
metadata. It can optionally expose a built-in remove action that dismisses the
chip from the DOM.
Static chips are not keyboard-focusable. A clickable chip makes its root focusable and button-like. A removable chip exposes its remove button as the tab stop. A chip that is both clickable and removable keeps its root as a plain container and moves the click action onto the label, so the label and the remove button are two sibling controls in the tab sequence. Disabled chips are removed from the tab order.
Usage
import { Chip } from '@takeoff-ui/react-spar';
<Chip removable>Business class</Chip>
Playground
Variants
Appearances
Sizes
Remove
The remove button is a real, labeled <button> in the tab sequence, so keyboard
and assistive-tech users can reach it directly and activate it with Enter or
Space. Its click reports through onRemove only — it never doubles as the
chip's onClick. A chip that is also clickable additionally accepts
Backspace or Delete while its click action (the label, in that layout) is
focused to request removal; those keys do nothing on the remove button itself.
Use onRemove to sync removal with application state. By default, a removable
chip dismisses itself after a remove action. Set autoDismiss={false} when the
parent owns the chip list — otherwise the chip's internal dismissed state and
the parent's list become two sources of truth.
Clickable
Use clickable when the chip performs an action, such as selecting a filter.
Clickable chips are keyboard-focusable and trigger their onClick handler with
Enter or Space. When a clickable chip is also removable, the label carries
the action (role="button") next to the remove button — a remove <button>
nested inside a role="button" root would be hidden from assistive tech.
Accessibility
- Static chip roots are not focusable.
- Clickable chips use a button-like root and support
EnterandSpace. - The remove button is a labeled control in the tab sequence and is activated
with
EnterorSpace. - Clickable removable chips place the click action on the label, beside the
remove button, so both controls are reachable; they also support
DeleteandBackspacewhile that action is focused. - Disabled chips do not receive focus (an explicit
tabIndexresolves to-1) and do not respond to remove actions.
API Reference
Chip
Props
| Name | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | - | Chip content. |
| variant | ChipVariant | 'primary' | Color variant. |
| appearance | ChipAppearance | 'filled' | Visual appearance. |
| size | ChipSize | 'base' | Size scale. |
| disabled | boolean | false | Disables interactive affordances and remove actions, and keeps the chip out of the tab order (a tabIndex given to a disabled chip resolves to -1). |
| removable | boolean | false | Renders a remove button that dismisses the chip from the DOM when pressed. |
| clickable | boolean | false | Makes the chip keyboard-focusable and button-like for click actions. The root carries the action; when the chip is also removable, the action moves onto the label slot so the remove button stays a sibling control that keyboard and assistive-tech users can reach separately. |
| autoDismiss | boolean | true | Whether the chip removes itself from the DOM after a remove action. Removal is tracked in internal state, so set autoDismiss={false} when the parent owns the chip list (e.g. renders chips from an array) and let onRemove drive the parent's state — otherwise the chip and the parent's list become two sources of truth. |
| classNames | Partial<Record<ChipSlot, string>> | - | Per-slot extra classes. |
| slotProps | Partial<Record<ChipSlot, React.HTMLAttributes<HTMLElement>>> | - | Per-slot HTML-attribute overrides. root.role / root.tabIndex describe the click action and follow it onto whichever node carries it (the root, or the label of a clickable removable chip); they resolve as instance role / tabIndex → slotProps.root → wrapper default. |
| className | string | - | Appends custom classes to the root slot. |
Events
| Name | Type | Default | Description |
|---|---|---|---|
| onRemove | () => void | - | Called when the remove button is pressed or a focused clickable chip receives Backspace/Delete. The remove button's click never doubles as the chip's onClick. |
Data attributes
| Attribute | Applied when | Purpose |
|---|---|---|
| data-slot="root" | Always | Stable selector for wrapper styling on the root slot. |
| data-variant | Always | Reflects the resolved variant prop for theme recipe scoping. |
| data-type | Always | Reflects the resolved appearance prop for theme recipe scoping. |
| data-size | Always | Reflects the resolved size prop for theme recipe scoping. |
| data-clickable | When clickable is true | Styling hook for chips with a click action. |
| data-disabled | When disabled is true | Styling hook for the disabled state. |
| data-removable | When removable is true | Styling hook for chip with a remove action. |
Type Definitions
| Name | Definition |
|---|---|
| ChipVariant | 'primary' | 'secondary' | 'neutral' | 'info' | 'success' | 'danger' | 'warning' | 'verified' | 'purple' | 'cyan' | 'business' | 'teal' | 'white' | 'dark' |
| ChipAppearance | 'filled' | 'filledLight' | 'outlined' |
| ChipSize | 'small' | 'base' | 'large' |
| ChipSlot | 'root' | 'label' | 'remove' |