Chip
Compact, interactive element for tags, filters, and selections — rendered as a span, div, button, or link.
Examples
<Chip> renders a <span> by default, styled with the color prop for one of Chassis's context
colors. It's a compact, composable building block for tags, filters, and selections — combine it
with Icon, Avatar, or CloseButton as plain children.
import { Chip } from '@chassis-ui/react'
export const Example = () => {
return <Chip color="primary">Chip</Chip>
}Colors
Set color to one of Chassis's context colors.
import { Chip } from '@chassis-ui/react'
import { COLORS } from '../../utils'
export const Example = () => {
return (
<>
{COLORS.map((color) => (
<Chip key={color} color={color}>
{color}
</Chip>
))}
</>
)
}Color alone doesn't convey meaning to assistive technology. Pair a context color with visible text describing the chip's purpose.
Style variants
Outline
Set variant="outline" for a transparent background with a colored border and text — a
lower-emphasis alternative to a solid chip in the same color.
import { Chip } from '@chassis-ui/react'
import { COLORS } from '../../utils'
export const Example = () => {
return (
<>
{COLORS.map((color) => (
<Chip key={color} color={color} variant="outline">
{color}
</Chip>
))}
</>
)
}Smooth
Set variant="smooth" for a subdued, tinted background in the chip's color.
import { Chip } from '@chassis-ui/react'
import { COLORS } from '../../utils'
export const Example = () => {
return (
<>
{COLORS.map((color) => (
<Chip key={color} color={color} variant="smooth">
{color}
</Chip>
))}
</>
)
}Icons
Nest an Icon at the start or end of a chip's content to add visual meaning. Wrap the text in its
own <span> so chassis-css's :first-child/:last-child spacing applies correctly.
import { Chip, Icon } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<Chip color="default">
<Icon name="info-circle-solid" aria-hidden="true" />
<span>Default</span>
</Chip>
<Chip color="primary">
<span>Primary</span>
<Icon name="info-circle-solid" aria-hidden="true" />
</Chip>
</>
)
}Avatars
Nest an Avatar to represent a person or entity — pair it with CloseButton for a removable
"selected person" chip. Pass component="span" to Avatar so it renders as a decorative image
rather than an interactive button.
import { Avatar, Chip, CloseButton } from '@chassis-ui/react'
export const Example = () => {
return (
<Chip color="default">
<Avatar src="https://i.pravatar.cc/256" component="span" />
Jane Doe
<CloseButton label="Remove Jane Doe" />
</Chip>
)
}Dismissible chips
Nest a CloseButton to add a removal action — Chip doesn't manage its own list state, so pair
it with an onClick handler that removes the value from whatever collection is being rendered
from.
import { useState } from 'react'
import { Chip, CloseButton } from '@chassis-ui/react'
export const Example = () => {
const [tags, setTags] = useState(['React', 'TypeScript', 'CSS'])
return (
<>
{tags.map((tag) => (
<Chip key={tag} color="primary">
{tag}
<CloseButton
label={`Remove ${tag}`}
onClick={() => setTags((current) => current.filter((value) => value !== tag))}
/>
</Chip>
))}
</>
)
}Sizes
Set size to "sm" or "lg" to adjust a chip's padding and font size; the default renders
at md size.
import { Chip } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<Chip color="primary" size="sm">
Small
</Chip>
<Chip color="primary">Medium</Chip>
<Chip color="primary" size="lg">
Large
</Chip>
</>
)
}Pressed state
Set pressed to mark a toggle-style chip as active — e.g. a filter pill that stays highlighted
while selected. It applies the .active class and sets aria-pressed, so assistive technology
announces the toggle state. Chip doesn't toggle itself; flip pressed from an onClick
handler. A chip that isn't a button gets the class alone: a static chip, and a chip that is a
link (href, or an <a> as component or the asChild element), which has no pressed state to
announce. Give a link chip role="button" if it acts as a toggle, and it takes aria-pressed
too.
import { useState } from 'react'
import { Chip } from '@chassis-ui/react'
export const Example = () => {
const [pressed, setPressed] = useState(false)
return (
<Chip component="button" color="primary" pressed={pressed} onClick={() => setPressed(!pressed)}>
In stock
</Chip>
)
}Root element
Set component to render <Chip> as a different element — "div" for a non-interactive block,
"button" for a toggle control, or any custom component. href implies component="a"
automatically.
import { Chip } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<Chip color="primary">Span</Chip>
<Chip component="div" color="primary">
Div
</Chip>
<Chip component="button" color="primary">
Button
</Chip>
<Chip href="#" role="button" color="primary">
Link
</Chip>
</>
)
}A chip rendered as <a> for something other than navigation — a toggle filter, for example —
needs an explicit role="button"; Chassis doesn't add it automatically, since not every
component="a" usage is a non-navigation action.
Disabled state
Set disabled to make a chip non-interactive. A <button> chip uses the real disabled
attribute, which blocks keyboard and pointer interaction on its own.
import { Chip } from '@chassis-ui/react'
export const Example = () => {
return (
<Chip component="button" color="primary" disabled>
Button
</Chip>
)
}<span>, <div>, and <a> have no disabled attribute, so a disabled non-button chip gets the
.disabled class instead, which sets pointer-events: none. A disabled <a> chip additionally
gets aria-disabled="true" and tabindex="-1", and blocks its own click handler and navigation.
import { Chip } from '@chassis-ui/react'
export const Example = () => {
return (
<Chip href="#" role="button" color="secondary" disabled>
Link
</Chip>
)
}Scope
No automatic role="button" on non-navigation links. Rendering <Chip> with component="a"
for a toggle action rather than navigation (see Root element) still needs an
explicit role="button" — Chassis can't distinguish the two cases from href alone.
No built-in list management. Unlike ChipInput, Chip
renders a single chip with no concept of a value collection — creation, removal, and keyboard
navigation across a set of chips are the consumer's responsibility (or use ChipInput, which
composes Chip internally for exactly that use case).
API
Chip
| Prop | Type | Default |
|---|---|---|
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
className? | string | — |
| A string of all className you want applied to the component. | ||
color? | ContextColor | — |
| Sets the color of the component to one of Chassis context colors. | ||
component? | ElementType | — |
Component used for the root node. Either a string to use a HTML element or a component.
Defaults to span, or a when href is set. | ||
disabled? | boolean | — |
Toggle the disabled state for the component. Applied as the native disabled attribute when
component is button, or the .disabled class for every other element (a bare <span>/
<a> has no real disabled attribute). | ||
href? | string | — |
Renders the chip as a link to this URL. Defaults component to a. | ||
onClick? | MouseEventHandler<HTMLElement> | — |
Fires on click. Typed for every element component can actually render, rather than
narrowed to whichever element C happens to be. | ||
pressed? | boolean | — |
Marks the chip as pressed for toggle-style usage (e.g. a filter chip). Applies the .active
class and sets aria-pressed so assistive technology announces the toggle state. A chip
with no onClick or component="button" is not a button and gets the class alone: a static
chip, and a link (href, or an <a> as component or the asChild element), which has no
pressed state to announce unless you give it role="button". | ||
ref? | any | — |
size? | "sm" | "lg" | — |
| Size the component sm or lg. | ||
type? | "button" | "submit" | "reset" | — |
Specifies the type of button. Only applies when component is button. Different browsers
may use different default types for the <button> element, so always specify it explicitly. | ||
variant? | ContextStyle | — |
Set the chip style variant. solid/basic render the default look with no extra class. | ||