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

# Migration

> Breaking changes and migration steps for @servicetitan/anvil2-ext-common releases.

Each breaking `@servicetitan/anvil2-ext-common` release gets a section here with before/after code, newest first.

## 0.8.x → 0.9.0

### Selection fields require selectable field states

`Form.Select`, `Form.SelectSync`, `Form.MultiSelect`, `Form.MultiSelectSync`, and `Form.TreeSelect` now require a `SelectableOptionsFieldState` (single) or `SelectableOptionsArrayFieldState` (multiple) instead of a bare `A2InputFieldState`.

**Before:**

```tsx theme={null}
import { Form, A2InputFieldState } from "@servicetitan/anvil2-ext-common";
import type { SelectFieldOption } from "@servicetitan/anvil2/beta";

const fruit = new A2InputFieldState<SelectFieldOption | null>(null);

<Form.Select fieldState={fruit} label="Fruit" loadOptions={loadOptions} />;
```

**After:**

```tsx theme={null}
import {
  Form,
  SelectableOptionsFieldState,
} from "@servicetitan/anvil2-ext-common";
import type { SelectFieldOption } from "@servicetitan/anvil2/beta";

const fruit = new SelectableOptionsFieldState<SelectFieldOption>(null);

<Form.Select fieldState={fruit} label="Fruit" loadOptions={loadOptions} />;
```

### Sync variants no longer accept an `options` prop

`Form.SelectSync` and `Form.MultiSelectSync` no longer take an `options` prop. Call `fieldState.setOptions(options)` instead.

**Before:**

```tsx theme={null}
import { Form, A2InputFieldState } from "@servicetitan/anvil2-ext-common";

const options = [
  { id: "email", label: "Email" },
  { id: "phone", label: "Phone" },
];
const contactType = new A2InputFieldState(null);

<Form.SelectSync
  fieldState={contactType}
  label="Contact type"
  options={options}
/>;
```

**After:**

```tsx theme={null}
import {
  Form,
  SelectableOptionsFieldState,
} from "@servicetitan/anvil2-ext-common";

const options = [
  { id: "email", label: "Email" },
  { id: "phone", label: "Phone" },
];
const contactType = new SelectableOptionsFieldState<(typeof options)[number]>(
  null,
);
contactType.setOptions(options);

<Form.SelectSync fieldState={contactType} label="Contact type" />;
```

### RadioGroup and CheckboxGroup values are full option objects

`Form.RadioGroup` and `Form.CheckboxGroup` field values are now the full selected option object(s), not bare id(s).

**Before:**

```tsx theme={null}
import {
  Form,
  SelectableOptionsArrayFieldState,
} from "@servicetitan/anvil2-ext-common";

const items = [
  { id: 1, label: "Email" },
  { id: 2, label: "SMS" },
];

// Value was the selected id(s)
const channels = new SelectableOptionsArrayFieldState<
  number,
  (typeof items)[number]
>([]);

// Reading the value
console.log(channels.value); // [1, 2] — array of ids
```

**After:**

```tsx theme={null}
import {
  Form,
  SelectableOptionsArrayFieldState,
} from "@servicetitan/anvil2-ext-common";

const items = [
  { id: 1, label: "Email" },
  { id: 2, label: "SMS" },
];

// Value is now the full option object(s)
const channels = new SelectableOptionsArrayFieldState<(typeof items)[number]>(
  [],
);

// Reading the value
console.log(channels.value); // [{ id: 1, label: "Email" }, { id: 2, label: "SMS" }] — array of option objects
```

### Selectable field states take a single generic

`SelectableOptionsFieldState` and `SelectableOptionsArrayFieldState` now take a single generic parameter `<G>` (the option type) instead of `<T, G>` (value type and option type).

**Before:**

```tsx theme={null}
import {
  SelectableOptionsFieldState,
  SelectableOptionsArrayFieldState,
} from "@servicetitan/anvil2-ext-common";

type Option = { id: number; label: string };

// Two generics: value type, then option type
const single = new SelectableOptionsFieldState<number, Option>(
  undefined as never,
);
const multi = new SelectableOptionsArrayFieldState<number, Option>([]);
```

**After:**

```tsx theme={null}
import {
  SelectableOptionsFieldState,
  SelectableOptionsArrayFieldState,
} from "@servicetitan/anvil2-ext-common";

type Option = { id: number; label: string };

// Single generic: the option type (value type is inferred)
const single = new SelectableOptionsFieldState<Option>(null);
const multi = new SelectableOptionsArrayFieldState<Option>([]);
```


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