> ## Documentation Index
> Fetch the complete documentation index at: https://anvil.servicetitan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Chip - Web

> Chips visually label and organize statuses, metadata, and objects.

> [!NOTE]
>
> For development, import `Chip` from
> `@servicetitan/anvil2`. For design, find it in the
> [Anvil2 file](https://www.figma.com/design/xaNQsvRKczoxu7pj0M6QT8/Anvil2-v3?node-id=173-5351).

![](https://mintcdn.com/servicetitan/uz2PQSvO75TRhQ38/images/docs/web/components/shared/example-of-chip-component.png?fit=max\&auto=format\&n=uz2PQSvO75TRhQ38\&q=85\&s=56b818b45a3d489ea4013ea40cd6f5be)

## Anatomy

The Chip consists of three primary elements that work together to visually label and organize information.

![Anatomy of the Chip
component](https://mintlify.s3.us-west-1.amazonaws.com/servicetitan/images/docs/web/components/chip/web/anatomy-of-the-chip-component.png)

1. Content
2. Close action
3. Custom background

## Options

The Chip supports prefix icons, prefix avatars, clickable and closeable actions, and custom colors to accommodate various labeling scenarios.

#### Clickable

chip-onclick

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-onclick?file=src/App.tsx)

```tsx lines theme={null}
import { Chip } from "@servicetitan/anvil2";

function App() {
  return <Chip label="Ben Ho" onClick={() => alert("chip click")} />;
}

export default App;
```

By default, a Chip is a non-clickable label. Use a clickable Chip for navigational contexts.

#### Close

chip-onclose

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-onclose?file=src/App.tsx)

```tsx lines theme={null}
import { Chip } from "@servicetitan/anvil2";

function App() {
  return <Chip label="Ben Ho" onClose={() => alert("chip close")} />;
}

export default App;
```

Chips can also have a close action, allowing a user to manually remove the Chip. Clickable and close can also be used together in a single Chip, but only when the size is set to medium.

### Prefix icon

chip-prefix-icon

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-prefix-icon?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";
import Warning from "@servicetitan/anvil2/assets/icons/material/round/warning.svg";

function App() {
  return (
    <Flex gap="4" alignItems="center">
      <Chip label="Needs review" icon={Warning} />
      <Chip label="Needs review" icon={Warning} size="small" />
    </Flex>
  );
}

export default App;
```

Place an icon before the label to reinforce what the Chip represents. The icon uses the same color as the label. A Chip includes one prefix: an icon or an avatar.

### Prefix avatar

chip-prefix-avatar

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-prefix-avatar?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";
import dog01 from "../assets/dog-01.png";

function App() {
  return (
    <Flex gap="4" alignItems="center">
      <Chip label="Ben Ho" avatar={dog01} />
      <Chip label="Ben Ho" avatar={dog01} size="small" />
    </Flex>
  );
}

export default App;
```

Place an avatar before the label to identify a person. Provide an image. When that image is unavailable, initials appear from the Chip label. Follow the [Avatar initials](https://anvil.servicetitan.com/docs/components/avatar/web.md#initials) guidance for how those initials are formed.

#### Custom background colors

chip-color

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-color?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";
import { core } from "@servicetitan/anvil2/token";

function App() {
  return (
    <Flex gap={2}>
      <Chip label="Chip" color={core?.primitive?.ColorPurple200.value} />
      <Chip label="Chip" color={core?.primitive?.ColorRed500.value} />
      <Chip label="Chip" color={core?.primitive?.ColorYellow300.value} />
      <Chip label="Chip" color={core?.primitive?.ColorNeutral500.value} />
    </Flex>
  );
}

export default App;
```

Chips provide one color by default. They can accept any color or Token value. Text color is auto-calculated to be the highest available contrast. It is suggested to use a Token value that supports theming.

#### AI Mark

Chips can display an AI mark icon to indicate AI-generated content.

chip-aimark

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-aimark?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";

function App() {
  return (
    <Flex gap="4" alignItems="center">
      <Chip label="AI job summary" aiMark />
      <Chip label="AI job summary" aiMark size="small" />
    </Flex>
  );
}

export default App;
```

By default, the AI mark uses a gradient treatment. When a custom background color is applied, the mark adapts to match the chip's text color for visual consistency.

chip-aimark-color

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-aimark-color?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";

function App() {
  return (
    <Flex gap="4" alignItems="center" wrap="wrap">
      <Chip label="AI job summary" aiMark color="#3e3e5f" />
      <Chip label="AI job summary" aiMark color="#7D165B" />
      <Chip label="AI job summary" aiMark color="#83ba43" />
      <Chip label="AI job summary" aiMark color="#DE9500" />
    </Flex>
  );
}

export default App;
```

> [!NOTE]
>
> When a Chip is clickable, the AI mark animates on hover to draw attention to the AI-generated content.

### Sizes

chip-size

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-size?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Grid } from "@servicetitan/anvil2";

function App() {
  return (
    <Grid templateColumns="repeat(3, max-content)" gap="2" alignItems="center">
      <Chip label="Medium Chip" size="medium" />
      <Chip label="Small Chip" size="small" />
    </Grid>
  );
}

export default App;
```

| Size | Height | Font size |
| - | - | - |
| Medium | 26px | 14px |
| Small | 18px | 12px |

Refer to the [choosing a chip size](#choosing-a-chip-size) section for more sizing recommendations.

## Behavior

The Chip responds to user interaction with distinct visual states and flexible overflow handling.

### Visual States

With custom colors, the hover background is lighter when the text is white, and darker when the text is black.

#### Without close

chip-data-interactive

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-data-interactive?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Grid } from "@servicetitan/anvil2";

function App() {
  return (
    <Grid templateColumns="repeat(3, max-content)" gap="8">
      <Chip label="Rest" onClick={() => alert("chip click")} />
      <Chip
        label="Hover"
        onClick={() => alert("chip click")}
        data-interactive="hover"
      />
      <Chip
        label="Focus Visible"
        onClick={() => alert("chip click")}
        data-interactive="focus-visible"
      />
    </Grid>
  );
}

export default App;
```

#### With close

chip-onclose-data-interactive

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-onclose-data-interactive?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Grid } from "@servicetitan/anvil2";

function App() {
  return (
    <Grid templateColumns="repeat(3, max-content)" gap="8">
      <Chip
        label="Rest"
        onClose={() => alert("chip close")}
        onClick={() => alert("chip click")}
      />
      <Chip
        label="Hover"
        onClose={() => alert("chip close")}
        onClick={() => alert("chip click")}
        data-interactive="close-hover"
      />
      <Chip
        label="Focus Visible"
        onClose={() => alert("chip close")}
        onClick={() => alert("chip click")}
        data-interactive="focus-visible"
      />
    </Grid>
  );
}

export default App;
```

### Overflow handling

#### Truncation

chip-textwrap-false

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-textwrap-false?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";

function App() {
  return (
    <Flex direction="column" gap={6} style={{ maxWidth: "455px" }}>
      <Chip
        label="Chip label that will wrap when not enough space is provided for it."
        size="medium"
      />
      <Chip
        label="Chip label that will wrap when not enough space is provided for it."
        size="medium"
        onClose={() => alert("chip close")}
      />
    </Flex>
  );
}

export default App;
```

By default, Chips will truncate, rather than wrap.

#### Wrapping

chip-textwrap

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-textwrap?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";

function App() {
  return (
    <Flex direction="column" gap={6}>
      <Chip
        label="Chip label that will wrap when not enough space isprovided for it."
        size="medium"
        textWrap
      />
      <Chip
        label="Chip label that will wrap when not enough space isprovided for it."
        size="medium"
        textWrap
        onClose={() => alert("chip close")}
      />
    </Flex>
  );
}

export default App;
```

Chips can be configured to individually wrap when there is not enough space.

#### Suggested group overflow

chip-group-wrap

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-group-wrap?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";

function App() {
  return (
    <Flex direction="column" gap={8} style={{ maxWidth: "455px" }}>
      <Flex gap={2} style={{ flexWrap: "wrap" }}>
        <Chip label="Chip" size="medium" />
        <Chip label="Longer Chip name" size="medium" />
        <Chip label="Another Chip name" size="medium" />
        <Chip label="One more to show wrapping " size="medium" />
      </Flex>

      <Flex gap={2} style={{ flexWrap: "wrap" }}>
        <Chip label="Chip" size="medium" />
        <Chip
          label="This is an exceptionally long Chip in the middle that could potentially break the whole layout"
          size="medium"
          textWrap
        />
        <Chip label="Another Chip name" size="medium" />
        <Chip label="One more to show wrapping " size="medium" />
      </Flex>
    </Flex>
  );
}

export default App;
```

The Chip on its own does not provide an opinion on grouping. Wrap groups first, prioritizing group wrapping before wrapping individual Chips.

## Usage Guidelines

Use the Chip when visually labeling and organizing statuses, metadata, and objects.

### When to Use

Use the Chip when:

* **Categorizing items** – Items need a short label that categorizes them or adds context, such as a status or a tag.
* **Groups of related labels** – Several labels describe the same item or set, and they sit together as a Chip group.
* **Navigational labels** – A label also leads somewhere; use a clickable Chip for navigational contexts.
* **Removable labels** – Users need to remove a label themselves; add a close action to the Chip.

### When not to use

Avoid using the Chip for:

* **Something requires attention** – The indicator signals that something requires attention, such as a notification; use a [Badge](https://anvil.servicetitan.com/docs/components/badge/web.md) instead.
* **Labeling everything on the page** – Chips add visual noise to the page, so use them in moderation.

### Alternatives

#### Chip vs Badge

Chips are used to categorize, label, and add context to items whereas Badges are used to indicate something requires attention, such as a notification. Additionally, Chips can be interactive while Badges are not.

### How to Use

#### Default

The default Chip visually highlights elements and provides user interaction.

chip-playground

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-playground?file=src/App.tsx)

```tsx lines theme={null}
import { Chip } from "@servicetitan/anvil2";

function App() {
  return (
    <Chip
      label="Ben Ho"
      size="medium"
      color="#3e3e5f"
      onClick={() => alert("chip click")}
      onClose={() => alert("chip close")}
    />
  );
}

export default App;
```

### Chip group

Chips are frequently paired together to form a Chip group.

chip-group

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-group?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";

function App() {
  return (
    <Flex gap={2}>
      <Chip label="Cat" />
      <Chip label="Dog" />
      <Chip label="Fish" />
    </Flex>
  );
}

export default App;
```

### Color

When implementing Chips, it is important to carefully consider what color is being used so that meaning and relationships are not implied when there is none.

For example, green is often meant to indicate "success" and red is used to indicate "danger" or "failure". Consistent usage is essential for helping users efficiently understand the status of something.

chip-color-semantic

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-color-semantic?file=src/App.tsx)

```tsx lines theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";
import { core } from "@servicetitan/anvil2/token";

function App() {
  return (
    <Flex gap={2}>
      <Chip
        label="Inspected"
        color={core.semantic?.StatusColorSuccess?.value}
      />
      <Chip label="Complete" color={core.semantic?.StatusColorWarning?.value} />
      <Chip label="Shipped" color={core.semantic?.StatusColorDanger?.value} />
    </Flex>
  );
}

export default App;
```

> [!WARNING]
>
> **Caution**

### Choosing a Chip size

Choose a Chip size based on its relative importance within the UI. Some general suggestions for Chips are provided below.

| | Medium Chip | Small Chip |
| - | - | - |
| Part of a [Tab](https://anvil.servicetitan.com/docs/components/tab/web.md) | ❌ | ✅ |
| Part of a [Side Nav](https://anvil.servicetitan.com/docs/components/side-nav/web.md) | ❌ | ✅ |
| Part of a [Combobox](https://anvil.servicetitan.com/docs/components/combobox/web.md) | ✅ | ❌ |
| Table Cell main content | ✅ | ⚠️ |
| Table Cell secondary content | ⚠️ | ✅ |
| Group of Chips on the page | ✅ | ⚠️ |
| Chip(s) in the page header | ✅ | ⚠️ |
| Needing an interactive Chip + close | ✅ | ❌ |

#### Legend

✅ recommended

⚠️ use with caution

❌ do not use

## Content

Content within the Chip should be short and descriptive, helping users understand context at a glance.

* Chips should be short and descriptive. Users should understand context at a glance.
* Use both color and text together to provide meaning so that color alone is not the only indicator of meaning.
* Use Chips in moderation as they add visual noise to the page.
* Chips may be used for both textual and numerical content.

## Keyboard Interaction

Users can navigate the Chip using standard keyboard controls.

#### With clickable Chip

| Key | Description |
| - | - |
| Enter | Engages the Chip and moves focus to the click target. |
| Backspace or Delete | If the close action exists, removes the Chip from the screen. |

### Accessibility

The Chip provides all accessibility needs out of the box. With custom background colors, the Chip will automatically provide a text color that will be at least a 4.5:1 ratio, satisfying WCAG AA requirements.

For more guidance on accessible interaction components, see [button accessibility best practices](https://anvil.servicetitan.com/docs/accessibility/labels-and-ctas.md#buttons-and-links).

## Code

**Implementation**

chip-playground

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-playground?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Chip } from "@servicetitan/anvil2";

function App() {
  return (
    <Chip
      label="Ben Ho"
      size="medium"
      color="#3e3e5f"
      onClick={() => alert("chip click")}
      onClose={() => alert("chip close")}
    />
  );
}

export default App;
```

## Common Examples

```tsx theme={null}
import { Chip } from "@servicetitan/anvil2";

function ExampleComponent() {
  return (
    <Chip
      label="Cassian Andor"
      size="medium"
      color="#3e3e5f"
      onClick={console.log}
      onClose={console.log}
    />
  );
}
```

### Basic Chip

`Chip` components must at least have their `label` prop defined, which will define the text that is displayed within the `Chip`.

chip-label

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-label?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Chip } from "@servicetitan/anvil2";

function App() {
  return <Chip label="Ben Ho" />;
}

export default App;
```

### Closeable Chip

Adding an `onClose` prop handler to the `Chip` component will render a clickable close button alongside the `Chip`.

chip-onclose

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-onclose?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Chip } from "@servicetitan/anvil2";

function App() {
  return <Chip label="Ben Ho" onClose={() => alert("chip close")} />;
}

export default App;
```

### Clickable Chip

Adding an `onClick` prop handler to the `Chip` component will render the text inside the `Chip` as a clickable button.

chip-onclick

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-onclick?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Chip } from "@servicetitan/anvil2";

function App() {
  return <Chip label="Ben Ho" onClick={() => alert("chip click")} />;
}

export default App;
```

### Chip with Avatar

Adding an `avatar` prop with a URL to an image will render an `Avatar` inside of the `Chip` as a prefix before the label. Note that the `avatar` prop cannot be used with the `icon` prop.

chip-avatar

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-avatar?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";
import dog01 from "../assets/dog-01.png";
import dog02 from "../assets/dog-02.png";

function App() {
  return (
    <Flex gap="6">
      <div>
        <Chip
          label="Ben Ho"
          onClose={() => alert("chip close")}
          color="#3e3e5f"
          avatar={dog01}
          textWrap
        />
      </div>

      <div style={{ width: "10rem" }}>
        <Chip
          label="Patrick Buckingham"
          onClose={() => alert("chip close")}
          color="#3e3e5f"
          avatar={dog02}
          textWrap
        />
      </div>
    </Flex>
  );
}

export default App;
```

### Chip with Icon

Adding an `icon` prop with an imported SVG will render an `Icon` inside of the `Chip` as a prefix before the label. Note that the `icon` prop cannot be used with the `avatar` prop.

chip-icon

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-icon?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";
import Info from "@servicetitan/anvil2/assets/icons/material/round/info.svg";
import Warning from "@servicetitan/anvil2/assets/icons/material/round/warning.svg";

function App() {
  return (
    <Flex gap="6">
      <div>
        <Chip
          label="Ben Ho"
          onClose={() => alert("chip close")}
          color="#3e3e5f"
          icon={Info}
          textWrap
        />
      </div>

      <div style={{ width: "10rem" }}>
        <Chip
          label="Patrick Buckingham"
          onClose={() => alert("chip close")}
          color="#3e3e5f"
          icon={Warning}
          textWrap
        />
      </div>
    </Flex>
  );
}

export default App;
```

### Chip with AI Mark

Adding the `aiMark` prop displays the `AiMark` icon inside the chip to indicate AI-generated content. On default chips (no color), a gradient AI mark is shown. On colored chips, the AI mark inherits the chip's text color.

chip-aimark

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-aimark?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";

function App() {
  return (
    <Flex gap="4" alignItems="center">
      <Chip label="AI job summary" aiMark />
      <Chip label="AI job summary" aiMark size="small" />
    </Flex>
  );
}

export default App;
```

#### AI Mark with Color

When a `color` prop is set alongside `aiMark`, the AI mark uses the default type, inheriting the chip's text color for visual cohesion.

chip-aimark-color

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-aimark-color?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";

function App() {
  return (
    <Flex gap="4" alignItems="center" wrap="wrap">
      <Chip label="AI job summary" aiMark color="#3e3e5f" />
      <Chip label="AI job summary" aiMark color="#7D165B" />
      <Chip label="AI job summary" aiMark color="#83ba43" />
      <Chip label="AI job summary" aiMark color="#DE9500" />
    </Flex>
  );
}

export default App;
```

#### AI Mark with Interactive Chips

When `aiMark` is used with `onClick`, the AI mark will animate when the chip is hovered or focused.

chip-aimark-interactive

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/chip-aimark-interactive?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Chip, Flex } from "@servicetitan/anvil2";

function App() {
  return (
    <Flex gap="4" alignItems="center" wrap="wrap">
      <Chip
        label="AI estimate draft"
        aiMark
        onClick={() => alert("chip click")}
      />
      <Chip
        label="AI estimate draft"
        aiMark
        onClose={() => alert("chip close")}
      />
      <Chip
        label="AI estimate draft"
        aiMark
        color="#3e3e5f"
        onClick={() => alert("chip click")}
        onClose={() => alert("chip close")}
      />
    </Flex>
  );
}

export default App;
```

## React Accessibility

* The `Chip` component won't be focusable unless it has an `onClick` or `onClose` prop handler defined.

For more guidance on accessible interaction components, see [button accessibility best practices](https://anvil.servicetitan.com/docs/accessibility/labels-and-ctas.md#buttons-and-links).

**Chip Props**

```tsx theme={null}
<Chip
  label="Cassian Andor"
  avatar="https://example.com/avatar.jpg"
  color="#3e3e5f"
  icon={StarIcon}
  size="medium"
  onClick={() => console.log("Clicked")}
  onClose={(e) => console.log("Closed")}
/>
```

## `Chip` Props

**label** `string` *required*

**aiMark** `boolean`

Displays an AI mark icon in the chip to indicate AI-generated content. Uses gradient style on default chips and inherited color style on colored chips.

**avatar** `string`

**Note:** Only works when `icon` is not set

**color** `string` (default: #14141429)

Several color formats work, such as HEX, RGB, HSL, HSV, etc.

**icon** `Svg`

**Note:** Only works when `avatar` is not set

**onClick** `() =\> void`

Setting this will make the chip clickable and focusable.
\[!NOTE] When `size="small"`, only one of `onClick` or `onClose` can be used, not both.

**onClose** `(e: MouseEvent | KeyboardEvent) =\> void`

Setting this will render the chip's close button.

> [!NOTE]
>
> When `size="small"`, only one of `onClick` or `onClose` can be used, not both.

**size** `"small" | "medium"` (default: medium)

**textWrap** `boolean`

Wraps text when it overflows.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.