Chip
Available from version 0.5.0
Chip generates a compact element that can represent an input, attribute, or action.
Basics
import { Chip } from 'tailwind-joy/components';
Chips comes with medium size, neutral color, and soft variant set by default.
import { Chip } from 'tailwind-joy/components';
export function ChipBasics() {
return (
<div>
<Chip>This is a chip</Chip>
</div>
);
}
Customization
Decorators
Use the startDecorator
and/or endDecorator
props to add supporting icons to the chip.
import { MdCloud, MdLightMode } from 'react-icons/md';
import { Box, Chip } from 'tailwind-joy/components';
import { iconClass } from 'tailwind-joy/utils';
export function ChipDecorators() {
return (
<Box className="flex items-center gap-2">
<Chip startDecorator={<MdLightMode className={iconClass()} />}>
Today is sunny
</Chip>
<Chip startDecorator={<MdCloud className={iconClass()} />}>
Tomorrow is cloudy
</Chip>
</Box>
);
}
Delete button
To add a delete action inside a chip, use the complementary ChipDelete
component.
The onDelete
callback is fired on ChipDelete
either when:
Backspace
,Enter
orDelete
is pressed.- The
ChipDelete
is clicked.
import { Box, Chip, ChipDelete } from 'tailwind-joy/components';
export function ChipDeleteButton() {
return (
<Box className="flex items-center gap-2">
<Chip
size="sm"
variant="outlined"
color="danger"
endDecorator={<ChipDelete onDelete={() => alert('Delete')} />}
>
Delete
</Chip>
<Chip
color="danger"
endDecorator={<ChipDelete onDelete={() => alert('Delete')} />}
>
Delete
</Chip>
<Chip
size="lg"
variant="solid"
color="danger"
endDecorator={<ChipDelete onDelete={() => alert('Delete')} />}
>
Delete
</Chip>
</Box>
);
}
Clickable
To make chips clickable, pass a function to the onClick
prop.
import { MdCheck } from 'react-icons/md';
import { Box, Chip } from 'tailwind-joy/components';
import { iconClass } from 'tailwind-joy/utils';
export function ChipClickable() {
return (
<Box className="flex items-center gap-2">
<Chip
size="lg"
variant="outlined"
startDecorator={
<div className="-ml-[9px] flex h-[22px] w-[22px] items-center justify-center overflow-hidden rounded-full">
<img
src="/img/avatar/octocat-avatar.png"
className="h-full w-full object-cover"
alt="Octocat"
/>
</div>
}
endDecorator={<MdCheck className={iconClass()} />}
onClick={() => alert('You clicked the Tailwind Joy Chip!')}
>
Octocat
</Chip>
</Box>
);
}
Clickable and deletable
Use both the onClick
prop and the complementary ChipDelete
component to make a chip support two actions.
import { MdDeleteForever } from 'react-icons/md';
import { Box, Chip, ChipDelete } from 'tailwind-joy/components';
import { iconClass } from 'tailwind-joy/utils';
export function ChipClickableAndDeletable() {
return (
<Box className="flex items-center gap-2">
<Chip
variant="outlined"
color="danger"
onClick={() => alert('You clicked the chip!')}
endDecorator={
<ChipDelete
variant="plain"
color="danger"
onClick={() => alert('You clicked the delete button!')}
>
<MdDeleteForever className={iconClass()} />
</ChipDelete>
}
>
Clear
</Chip>
</Box>
);
}
With radio
Common to filtering UIs, wrap the Radio
component with the Chip
to use them together.
Use radios when you want to enable single selection.
Best Movie
import { useState } from 'react';
import { MdCheck } from 'react-icons/md';
import {
Box,
Chip,
Radio,
RadioGroup,
Typography,
} from 'tailwind-joy/components';
import { iconClass } from 'tailwind-joy/utils';
import { twMerge } from 'tailwind-merge';
export function ChipWithRadio() {
const [selected, setSelected] = useState('');
return (
<Box className="flex items-center gap-2">
<div>
<Typography level="title-lg" className="mb-4">
Best Movie
</Typography>
<RadioGroup
name="best-movie"
orientation="horizontal"
className="flex-wrap gap-2"
>
{[
'Star trek',
'Batman',
'Spider man',
'Eternals',
'Shang chi',
'Jungle cruise',
'No time to die',
'Thor',
'The hulk',
].map((name) => {
const checked = selected === name;
return (
<Chip
key={name}
variant="plain"
color={checked ? 'primary' : 'neutral'}
startDecorator={
checked && (
<MdCheck
className={twMerge(
iconClass(),
'pointer-events-none z-[1]',
)}
/>
)
}
>
<Radio
variant="outlined"
color={checked ? 'primary' : 'neutral'}
disableIcon
overlay
label={name}
value={name}
checked={checked}
onChange={(event) => {
if (event.target.checked) {
setSelected(name);
}
}}
/>
</Chip>
);
})}
</RadioGroup>
</div>
</Box>
);
}
With checkbox
Similar to the above, wrap the Checkbox
component with the Chip
to use them together.
Use checkboxes when you want to enable multiple selection.
Favorite Movies
import { useState } from 'react';
import { MdCheck } from 'react-icons/md';
import { Box, Checkbox, Chip, Typography } from 'tailwind-joy/components';
import { iconClass } from 'tailwind-joy/utils';
import { twMerge } from 'tailwind-merge';
export function ChipWithCheckbox() {
const [selected, setSelected] = useState<string[]>([]);
return (
<Box className="flex items-center gap-2">
<div>
<Typography level="title-lg" className="mb-4">
Favorite Movies
</Typography>
<Box role="group" className="flex flex-wrap gap-2">
{[
'Star trek',
'Batman',
'Spider man',
'Eternals',
'Shang chi',
'Jungle cruise',
'No time to die',
'Thor',
'The hulk',
].map((name) => {
const checked = selected.includes(name);
return (
<Chip
key={name}
variant="plain"
color={checked ? 'primary' : 'neutral'}
startDecorator={
checked && (
<MdCheck
className={twMerge(
iconClass(),
'pointer-events-none z-[1]',
)}
/>
)
}
>
<Checkbox
variant="outlined"
color={checked ? 'primary' : 'neutral'}
disableIcon
overlay
label={name}
checked={checked}
onChange={(event) => {
setSelected((names) =>
!event.target.checked
? names.filter((n) => n !== name)
: [...names, name],
);
}}
/>
</Chip>
);
})}
</Box>
</div>
</Box>
);
}
Anatomy
The Chip component is composed of a single root <div>
element that wraps around its contents:
<div class="tj-chip-root ...">
<!-- action button is nested here when clickable -->
<span class="tj-chip-label ...">
<!-- Chip contents -->
</span>
<!-- start decorator is nested here when present -->
<!-- end decorator is nested here when present -->
</div>
API
See the documentation below for a complete reference to all of the props available to the components mentioned here.