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

# Diff Value - Web

> Diff values highlight changes between previous and updated values.

> [!NOTE]
>
> For development, import `DiffValue` from
> `@servicetitan/anvil2-ai-kit`. For design, find it in the
> [AI Kit Web Component Library file](https://www.figma.com/design/QEIsArLktLeJAaFvcpw3PO/AI-Kit-Web-Component-Library).

ai-kit-diff-value

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

```tsx lines theme={null}
import { DiffValue } from "@servicetitan/anvil2-ai-kit";

function App() {
  return <DiffValue from="6.5h" to="8.0h" />;
}

export default App;
```

## Options

The Diff Value supports empty and removed source values, and renders either an inline or a block layout.

### Empty and Removed Values

ai-kit-diff-value-empty-and-removed-values

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-diff-value-empty-and-removed-values?file=src/App.tsx)

```tsx lines theme={null}
import { DiffValue, Text } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      <div>
        <Text variant="eyebrow" text="Empty to value" />
        <DiffValue to="8.0h" />
      </div>
      <div>
        <Text variant="eyebrow" text="Value to removed" />
        <DiffValue from="6.5h" />
      </div>
    </div>
  );
}

export default App;
```

Omit or pass `null` for `from` to render `(Empty)` — there was no prior value. Omit or pass `null` for `to` to render the highlighted `(Removed)` label — the value was taken away entirely.

### Layout

ai-kit-diff-value-layout-inline

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-diff-value-layout-inline?file=src/App.tsx)

```tsx lines theme={null}
import { DiffValue } from "@servicetitan/anvil2-ai-kit";

function App() {
  return <DiffValue from="6.5h" to="8.0h" layout="inline" />;
}

export default App;
```

ai-kit-diff-value-layout-block

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-diff-value-layout-block?file=src/App.tsx)

```tsx lines theme={null}
import { DiffValue } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ maxWidth: "28rem" }}>
      <DiffValue
        from="Standard repair visit with one replacement part."
        to="Extended repair visit including compressor diagnostics, refrigerant recharge, and replacement of the contactor and capacitor per technician notes."
        layout="block"
      />
    </div>
  );
}

export default App;
```

Layout defaults to `inline` for short values on a single line, and `block` — stacking `from` above `to` — once either side exceeds roughly 80 characters or contains a newline. Pass `layout` explicitly to override the automatic choice.

## Behavior

The Diff Value is otherwise static; only its block layout can become interactive when text is truncated.

### Truncation

ai-kit-diff-value-truncation

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

```tsx lines theme={null}
import { DiffValue } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ maxWidth: "28rem" }}>
      <DiffValue
        from="The AI Adoption Maturity Model is a framework for assessing the ability of an organization to perform and sustain specific technical practices to achieve two key, high-level goals."
        to="Revised invoice summary with additional labor detail and updated scope notes that exceed the inline threshold for block layout rendering."
        layout="block"
        truncateLines={2}
      />
    </div>
  );
}

export default App;
```

In block layout, text beyond `truncateLines` (default `2`) clips with a "Show more" control that expands it in place; an expanded side shows "Show less" to collapse it again. Each side truncates independently.

## Usage Guidelines

### When to Use

Use the Diff Value when:

* **Showing a changed value** – The reader needs to see both the previous value and the updated value, such as labor hours changing from 6.5h to 8.0h.
* **Adding a value where none existed** – Omit the previous value to show "(Empty)" before the new value.
* **Removing a value** – Omit the updated value to show the highlighted "(Removed)" label.
* **Comparing long text** – Either value runs past a single line. The block layout stacks the previous value above the updated value and truncates each side with a Show more control.

### When not to use

Avoid using the Diff Value for:

* **Showing only the revised value** – The previous value isn't needed. Use the [Text](https://anvil.servicetitan.com/docs/components/text/ai-kit.md) with the highlighted treatment, or the [Truncated Text](https://anvil.servicetitan.com/docs/components/truncated-text/web.md) for long body copy, instead.
* **Asking the user to accept, edit, or reject proposed changes** – The Diff Value is static. Use the [Guidance Card](https://anvil.servicetitan.com/docs/components/guidance-card/web.md) instead, which renders each change as a Diff Value with selection and review actions.

## Keyboard Interaction

The diff itself is static text and is not part of the tab sequence. When block layout truncates a side, its "Show more" / "Show less" control is a standard button.

| Key | Description |
| - | - |
| Tab | Moves focus to a visible "Show more" or "Show less" control |
| Enter / Space | Toggles the focused control's expanded state |

## Code

**Implementation**

ai-kit-diff-value

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

```tsx lines expandable theme={null}
import { DiffValue } from "@servicetitan/anvil2-ai-kit";

function App() {
  return <DiffValue from="6.5h" to="8.0h" />;
}

export default App;
```

## Common Examples

To use the `DiffValue`, import it from `@servicetitan/anvil2-ai-kit` and pass the previous value through `from` and the proposed value through `to`.

```tsx theme={null}
import { DiffValue } from "@servicetitan/anvil2-ai-kit";

function ExampleComponent() {
  return <DiffValue from="6.5h" to="8.0h" />;
}
```

### Automatic layout

`DiffValue` uses inline layout for short, single-line values. It switches to block layout when either value exceeds 80 characters or contains a newline. Pass `layout` to override the automatic choice.

ai-kit-diff-value-layout-inline

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-diff-value-layout-inline?file=src/App.tsx)

```tsx lines expandable theme={null}
import { DiffValue } from "@servicetitan/anvil2-ai-kit";

function App() {
  return <DiffValue from="6.5h" to="8.0h" layout="inline" />;
}

export default App;
```

ai-kit-diff-value-layout-block

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-diff-value-layout-block?file=src/App.tsx)

```tsx lines expandable theme={null}
import { DiffValue } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ maxWidth: "28rem" }}>
      <DiffValue
        from="Standard repair visit with one replacement part."
        to="Extended repair visit including compressor diagnostics, refrigerant recharge, and replacement of the contactor and capacitor per technician notes."
        layout="block"
      />
    </div>
  );
}

export default App;
```

### Empty and removed values

Omit `from`, pass `null`, or pass whitespace to render the localized empty label. Do the same for `to` to render the localized removed label.

ai-kit-diff-value-empty-and-removed-values

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-diff-value-empty-and-removed-values?file=src/App.tsx)

```tsx lines expandable theme={null}
import { DiffValue, Text } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      <div>
        <Text variant="eyebrow" text="Empty to value" />
        <DiffValue to="8.0h" />
      </div>
      <div>
        <Text variant="eyebrow" text="Value to removed" />
        <DiffValue from="6.5h" />
      </div>
    </div>
  );
}

export default App;
```

### Truncation

Block layout uses [`TruncatedText`](https://anvil.servicetitan.com/docs/components/truncated-text/code). Set `truncateLines` to control the collapsed line limit.

ai-kit-diff-value-truncation

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

```tsx lines expandable theme={null}
import { DiffValue } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ maxWidth: "28rem" }}>
      <DiffValue
        from="The AI Adoption Maturity Model is a framework for assessing the ability of an organization to perform and sustain specific technical practices to achieve two key, high-level goals."
        to="Revised invoice summary with additional labor detail and updated scope notes that exceed the inline threshold for block layout rendering."
        layout="block"
        truncateLines={2}
      />
    </div>
  );
}

export default App;
```

## Internationalization

`DiffValue` uses three messages:

* `ai-kit.diffValue.empty`
* `ai-kit.diffValue.removed`
* `ai-kit.diffValue.changedFromTo`

English is the default. Mount `AiKitIntlProvider` inside `CartoTheme` to switch locale or override these strings. The `changedFromTo` message receives `{from}` and `{to}` values.

```tsx theme={null}
<AiKitIntlProvider
  messages={{
    "ai-kit.diffValue.empty": "Empty",
    "ai-kit.diffValue.removed": "Removed",
    "ai-kit.diffValue.changedFromTo": "Changed from {from} to {to}",
  }}
>
  <DiffValue from="Draft" to="Approved" />
</AiKitIntlProvider>
```

## React Accessibility

* A visually hidden localized summary announces the relationship as "Changed from X to Y."
* Inline layout hides duplicate visual values from assistive technology.
* Block layout keeps Show more and Show less controls reachable when either value is truncated.
* The arrow is decorative and hidden from assistive technology.

**DiffValue Props**

```tsx theme={null}
<DiffValue
  from="Previous value"
  to="Proposed value"
  layout="block"
  truncateLines={2}
/>
```

## `DiffValue` Props

The `DiffValue` accepts the following props.

**className** `string`

Class merged onto the root element.

**from** `string | null`

Previous value. Omit, pass `null`, or pass only whitespace to render the
localized empty label.

**layout** `"inline" | "block"`

Layout mode. When omitted, long or multiline values use `"block"` and
other values use `"inline"`.

**to** `string | null`

Proposed value. Omit, pass `null`, or pass only whitespace to render the
localized removed label.

**truncateLines** `number` (default: 2)

Maximum lines before truncation in block layout.


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