> ## 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.

# Anvil2 1.0 to 2.0

## Migrating from Anvil2 1.x to 2.0

Anvil2 2.0 is a **major release** that removes all previously deprecated APIs, standardizes component composition, and updates several required props. Because deprecated APIs have been **fully removed**, upgrading from v1.x will surface **build-time errors** that must be resolved before your application can compile.

This guide walks through the required changes and common migration patterns.

<Note>
  * Deprecated components and props have been **removed** and will now throw build errors
  * Several internal sub-exports that were accidentally surfaced are **no longer exported**; use the existing compound/component namespace API instead
  * Several previously optional props are now **required**
  * Overlay components no longer have a **fallback** for browsers without HTML Popover support.
  * Some Icon filenames have been renamed for consistency
</Note>

## Component Behavior Changes

### Chip

When using `size="small"`, `Chip` now allows **only one** of the following props:

* `onChange`
* `onClose`

```tsx theme={null}
// ❌ Invalid
<Chip size="small" onChange={handleChange} onClose={handleClose} />

// ✅ Valid
<Chip size="small" onChange={handleChange} />
```

***

## Overlay Components

The following components using the **HTML Popover API** no longer have a fallback:

* `Tooltip`
* `Popover`
* `Menu`
* `Combobox`

No API changes are required, but this change requires that consumers of Anvil2 use a browser that is [compatible with the HTML Popover API](https://caniuse.com/?search=popover).

***

## Removed Exports → Compound Component APIs

Several components previously exposed internal sub-exports at the package surface. Those internal exports are now removed from the public surface. Use the existing compound / namespaced APIs instead.

### Dialog

```tsx theme={null}
// ❌ Removed exports
import {
  DialogContent,
  DialogHeader,
  DialogFooter,
  DialogCancelButton,
} from "@servicetitan/anvil2";

// ✅ Use the compound API
<Dialog>
  <Dialog.Header />
  <Dialog.Content />
  <Dialog.Footer />
  <Dialog.CancelButton />
</Dialog>
```

***

### SideNav

```tsx theme={null}
// ❌ Removed exports
import { SideNavLink, SideNavGroup } from "@servicetitan/anvil2";

// ✅ Use the compound API
<SideNav>
  <SideNav.Group>
    <SideNav.Link />
  </SideNav.Group>
</SideNav>
```

***

### Other Components Using the Same Pattern

| Component   | Removed Export(s)                                                   | Replacement API                                    |
| ----------- | ------------------------------------------------------------------- | -------------------------------------------------- |
| Breadcrumbs | `BreadcrumbsElement`                                                | `Breadcrumbs`                                      |
| Checkbox    | `CheckboxGroup`                                                     | `Checkbox.Group`                                   |
| Details     | `DetailsSummary`, `DetailsContent`                                  | `Details.Summary`, `.Content`                      |
| Popover     | `PopoverTrigger`, `PopoverContent`, `PopoverClose`, `PopoverButton` | `Popover.Trigger`, `.Content`, `.Close`, `.Button` |
| Radio       | `RadioGroup`                                                        | `Radio.Group`                                      |
| SelectCard  | `SelectCardElement`, `SelectCardGroup`                              | `SelectCard`, `SelectCard.Group`                   |
| Toolbar     | `ToolbarElement`, `ToolbarButton`, `ToolbarSelect`                  | `Toolbar`, `Toolbar.Button`, `.Select`             |

***

## Removed Components

### DateField

The deprecated `DateField` component has been **removed**.

```tsx theme={null}
// ✅ Replace with one of:
<DateFieldSingle />
<DateFieldRange />
```

***

## Removed / Replaced Props

All deprecated props have been removed in 2.0 and will now cause **build errors**.

## Dialog

* Removed:
  * `onOpen`
  * `onOpenChange`
* Use instead:
  * `onOpenAnimationStart`
  * `onOpenAnimationComplete`
  * `onClose`

***

### Popover

* Removed:
  * `onOpenChange`
  * `onOutsidePress`
  * `disableFocusLock`
  * `root`
* Replacements:
  * `onClickOutside`
  * `modal`

```tsx theme={null}
// ❌ Removed
<Popover onOutsidePress={handleOutside} disableFocusLock root />

// ✅ Updated
<Popover onClickOutside={handleOutside} modal />
```

* `Popover.Trigger`
  * `data-state` has been replaced with `aria-expanded`

***

### Drawer

* Removed: `onOpen`
* Use:
  * `onOpenAnimationStart`
  * `onOpenAnimationComplete`

***

### Calendar

```tsx theme={null}
// ❌ Removed
unavailableDates

// ✅ New API
unavailable={{ dates: [...] }}
```

***

### Flex

`flexShrink` has been replaced by `shrink`.

```tsx theme={null}
// ❌
<Flex flexShrink="1" />

// ✅
<Flex shrink="1" />
```

***

### Textarea

* `errorAriaLive` no longer accepts a boolean

```tsx theme={null}
// ❌
errorAriaLive={true}

// ✅
errorAriaLive="assertive" // "polite" | "off"
```

***

### Toaster

* Removed:
  * `duration`
  * `forceRender`

Toast duration must now be set on **individual toasts**.

***

### Field-Level `openMoreInfo`

Removed from the following components:

* `FieldLabel`
* `Combobox.Trigger`
* `SelectTrigger`
* `Textarea`

```tsx theme={null}
// ❌
openMoreInfo

// ✅
moreInfoOpen
```

***

### Link

```tsx theme={null}
// ❌
<Link quiet />

// ✅
<Link ghost />
```

***

## Newly Required Props

The following props are now **required** and must be provided to avoid build errors:

| Component        | Required Prop |
| ---------------- | ------------- |
| `RadioGroup`     | `legend`      |
| `Toolbar.Button` | `onClick`     |

***

## Icon Renames

Several icons were renamed for consistency. Update any imports or asset references accordingly:

| Old Name                         | New Name                          |
| -------------------------------- | --------------------------------- |
| `gnav_dial_pad_filled.svg`       | `gnav_dial_pad_active.svg`        |
| `gnav_dial_pad_inactive_outline` | `gnav_dial_pad_disabled.svg`      |
| `gnav_dial_pad_outline.svg`      | `gnav_dial_pad_inactive.svg`      |
| `gnav_home_filled.svg`           | `gnav_home_active.svg`            |
| `gnav_home_outline.svg`          | `gnav_home_inactive.svg`          |
| `gnav_legacy_search_filled.svg`  | `gnav_legacy_search_active.svg`   |
| `gnav_legacy_search_outline.svg` | `gnav_legacy_search_inactive.svg` |

***

## Optional: Anvil2 v2 Migration Claude Skill

To help teams prepare for the Anvil2 v2 migration, an optional Claude skill is available that scans the codebase for **deprecated Anvil2 patterns** and applies safe, mechanical fixes where possible.

> **Thanks to Kiryl Chetyrbak** for creating and sharing this Claude skill.

Script location:\
[https://github.com/servicetitan/ai-codegen-tools/blob/master/plugins/skills/preparing-anvil2-migration/SKILL.md](https://github.com/servicetitan/ai-codegen-tools/blob/master/plugins/skills/preparing-anvil2-migration/SKILL.md)

### What the script does

The script performs a structured migration pass with the following workflow:

1. Scans the codebase for known Anvil2 v2 deprecations
2. Applies **automatic fixes** for clear, unambiguous replacements
3. Flags items that require **manual decisions or review**, including file locations
4. Produces a summary of changes made and remaining action items

### Types of changes it handles

The script covers a broad set of Anvil2 v2 migration rules, including:

* **Renamed exports and components**
  * e.g. `BreadcrumbsElement → Breadcrumbs`
* **Pascal-case subcomponents migrated to dot notation**
  * e.g. `DialogContent → Dialog.Content`
* **Icon naming changes**
  * e.g. `*_filled → *_active`
* **Prop renames and removals**
  * e.g. `quiet → ghost`, removed `Menu.open`
* **Event handler changes**
  * e.g. `onOpen → onOpenAnimationStart / End`
* **Component replacements**
  * e.g. `DateField → DateFieldSingle / DateFieldRange`
* **Import path updates**
  * e.g. `TooltipContext` moved to `@servicetitan/anvil2/base`
* **Context-based fixes**
  * Infers missing `RadioGroup` legends
  * Chooses `DateFieldSingle` vs `DateFieldRange` based on usage

### Decisions that require manual input

Some migrations cannot be resolved automatically. In these cases, the script will stop and ask for guidance, for example:

* `Chip size="small"` with both `onClick` and `onClose`
* `Toolbar.Button` without an `onClick` handler

### What this script does *not* do

* It does **not** guarantee full Anvil2 v2 compatibility
* It does **not** replace manual review or testing
* It should not be treated as a one-click migration

### When to use it

We recommend running this script **early in the migration process** to:

* Reduce manual discovery of deprecated patterns
* Apply consistent, mechanical fixes automatically
* Surface migration decisions before deeper refactors begin

<Note>
  This script is a convenience tool, not a required or officially supported migration step. Teams remain responsible for validating behavior, accessibility, and visual correctness after migration.
</Note>
