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

# Details - Web

> Details are accordions that show or hide information when clicked.

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

![](https://mintcdn.com/servicetitan/uz2PQSvO75TRhQ38/images/docs/web/components/shared/details-main-image.png?fit=max\&auto=format\&n=uz2PQSvO75TRhQ38\&q=85\&s=327ac14a3d65db4be6a08123ce240119)

## Anatomy

The Details consists of three primary elements that work together to show or hide information when clicked.

![Details
anatomy](https://mintcdn.com/servicetitan/lX6UhRsjMdTeB7y6/images/docs/web/components/details/design/details-anatomy.png?fit=max\&auto=format\&n=lX6UhRsjMdTeB7y6\&q=85\&s=256eb3702e3c120de6ffab3f6629b704)

1. Chevron
2. Heading
3. Body content

## Options

The Details supports flexible content configurations to accommodate various accordion scenarios.

details-playground

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

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

function App() {
  return (
    <div style={{ maxWidth: "23rem" }}>
      <Details>
        <Details.Summary>Click to see details.</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details>
        <Details.Summary>Click to see details.</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
    </div>
  );
}

export default App;
```

## Behavior

The Details responds to user interaction with flexible opening and closing behaviors while handling content overflow.

### Closed by default

details-defaultexpanded

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

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

function App() {
  return (
    <div style={{ maxWidth: "23rem" }}>
      <Details>
        <Details.Summary>Closed by default Details heading</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details defaultExpanded>
        <Details.Summary>Open by default Details heading</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
    </div>
  );
}

export default App;
```

Details are closed until clicked by default. Configure them to open by default when showing this content immediately.

### Opening behavior

details-accordion-false

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

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

function App() {
  return (
    <div style={{ maxWidth: "23rem" }}>
      <Details>
        <Details.Summary>Independent Details</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details>
        <Details.Summary>Independent Details</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details>
        <Details.Summary>Independent Details</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
    </div>
  );
}

export default App;
```

details-accordion

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

```tsx lines theme={null}
import { Details, type DetailsProps } from "@servicetitan/anvil2";
import { useState } from "react";

function App() {
  const [expanded, setExpanded] = useState<string | undefined>("2");
  const expandDetails = (id: DetailsProps["id"]) => {
    setExpanded((prev) => (prev === id ? undefined : id));
  };

  return (
    <div style={{ maxWidth: "23rem" }}>
      <Details
        id="1"
        expanded={expanded === "1"}
        onClick={() => expandDetails("1")}
      >
        <Details.Summary>One open at a time Details</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details
        id="2"
        expanded={expanded === "2"}
        onClick={() => expandDetails("2")}
      >
        <Details.Summary>One open at a time Details</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details
        id="3"
        expanded={expanded === "3"}
        onClick={() => expandDetails("3")}
      >
        <Details.Summary>One open at a time Details</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
    </div>
  );
}

export default App;
```

By default, individual Details open and close independently of each other. Configure them to work like an accordion, where only 0 to 1 individual Details is open at once.

### Heading overflow

details-overflow-summary

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

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

function App() {
  return (
    <div style={{ maxWidth: "23rem" }}>
      <Details>
        <Details.Summary>
          This is a very long Details heading that will wrap when there is not
          enough room for it to be on one line.
        </Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
    </div>
  );
}

export default App;
```

Long headings will wrap when there is not enough room for it to be on one line.

The chevron indicator will be vertically centered with the height of the heading.

### Content overflow

details-overflow-content

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

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

function App() {
  return (
    <div style={{ maxWidth: "23rem" }}>
      <Details defaultExpanded>
        <Details.Summary>Without a max height</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details defaultExpanded>
        <Details.Summary>With a max height</Details.Summary>
        <Details.Content maxHeight="3.3rem">
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
    </div>
  );
}

export default App;
```

Body content for Details will display in full unless a specific height is set. When a height is set, the body content will appear with a scrollbar.

## Usage Guidelines

| Standard | Requirement |
| - | - |
| DoShow or hide info in tight spaces | Details are a collapsible accordion for showing or hiding additional information, and are helpful in contexts where vertical space is limited. |
| DoProvide non-critical context | Use Details as supplementary information that is not critical to completing a task. |
| Don'tHide essential task information | Details should not be used to hide information essential for the user to complete a task. |
| Don'tConceal lengthy content | Details should not be used to conceal lengthy content. It's recommended to use Tabs in this case. |

### Alternatives

#### Details vs Tab

Details are used to show additional information around a sub-topic on a page, while a Tab categorizes information. The context of Details is small, non-essential information, while Tabs can categorize both small and large, essential and non-essential information.

### How to Use

#### In a group with other Details

Use Details as supplementary information that is not critical to completing a task.

details-supplementary-group

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

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

function App() {
  return (
    <div style={{ maxWidth: "23rem" }}>
      <Details>
        <Details.Summary>How do I reset my password?</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details>
        <Details.Summary>Where do I find my member ID?</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details>
        <Details.Summary>When does my account expire?</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
    </div>
  );
}

export default App;
```

## Content

Content within the Details should provide supplementary information that enhances understanding without being critical to task completion.

## Keyboard Interaction

Users can navigate the Details using standard keyboard controls.

| Key | Description |
| - | - |
| Tab | Move to the next tab-able element within the Details or the page. |
| Space or Enter | Opens/Closes the Details component |

## Code

**Implementation**

details-playground

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

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

function App() {
  return (
    <div style={{ maxWidth: "23rem" }}>
      <Details>
        <Details.Summary>Click to see details.</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details>
        <Details.Summary>Click to see details.</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
    </div>
  );
}

export default App;
```

## Common Examples

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

function ExampleComponent() {
  return (
    <Details>
      <Details.Summary>Click to expand</Details.Summary>
      <Details.Content>Lorem ipsum dolor sit amet.</Details.Content>
    </Details>
  );
}
```

### JSX content in details

The `children` prop of the `Details` component can accept any `ReactNode`. In many cases, text will be all that is required. In more complex scenarios, other Anvil2 components and JSX can be used.

details-children

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

```tsx lines expandable theme={null}
/* eslint-disable jsx-a11y/anchor-is-valid */
import { Details, Flex, Text } from "@servicetitan/anvil2";

function App() {
  return (
    <Details>
      <Details.Summary>Need more help?</Details.Summary>
      <Details.Content>
        <Flex gap="6">
          <div>
            <Text variant="headline" el="h3">
              Reach Out
            </Text>
            <ul>
              <li>
                <a href="#">(800) 555-1234</a>
              </li>
              <li>
                <a href="#">help@acmeplumbing.com</a>
              </li>
            </ul>
          </div>
          <div>
            <Text variant="headline" el="h3">
              Useful Links
            </Text>
            <ul>
              <li>
                <a href="#">acmeplumbing.com/help</a>
              </li>
              <li>
                <a href="#">acmeplumbing.com/faqs</a>
              </li>
            </ul>
          </div>
        </Flex>
      </Details.Content>
    </Details>
  );
}

export default App;
```

### Controlling details

By default, the `Details` component is uncontrolled and expands/collapses based on user input (on click or on enter or space key press when the element is focused). Use the `expanded` prop to control the details expanded state programatically.

details-expanded

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

```tsx lines expandable theme={null}
import { Details, Flex, Button } from "@servicetitan/anvil2";
import { useState } from "react";

function App() {
  const [expanded, setExpanded] = useState(false);
  const toggleExpanded = () => {
    setExpanded((prev) => !prev);
  };

  return (
    <Flex justifyContent="space-between">
      <Button onClick={toggleExpanded}>Toggle expanded</Button>
      <Details expanded={expanded} onClick={toggleExpanded}>
        <Details.Summary>Click to see details</Details.Summary>
        <Details.Content>Lorem ipsum dolor sit amet.</Details.Content>
      </Details>
    </Flex>
  );
}

export default App;
```

### Accordions

To create an accordion-style details list, control the open state of each item using the `expanded` on `onClick` props.

details-accordion

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

```tsx lines expandable theme={null}
import { Details, type DetailsProps } from "@servicetitan/anvil2";
import { useState } from "react";

function App() {
  const [expanded, setExpanded] = useState<string | undefined>("2");
  const expandDetails = (id: DetailsProps["id"]) => {
    setExpanded((prev) => (prev === id ? undefined : id));
  };

  return (
    <div style={{ maxWidth: "23rem" }}>
      <Details
        id="1"
        expanded={expanded === "1"}
        onClick={() => expandDetails("1")}
      >
        <Details.Summary>One open at a time Details</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details
        id="2"
        expanded={expanded === "2"}
        onClick={() => expandDetails("2")}
      >
        <Details.Summary>One open at a time Details</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details
        id="3"
        expanded={expanded === "3"}
        onClick={() => expandDetails("3")}
      >
        <Details.Summary>One open at a time Details</Details.Summary>
        <Details.Content>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
    </div>
  );
}

export default App;
```

### Details content height options

The following props are available to control the height of the details content: `height` and `maxHeight`. If either is set, the content element will also have `overflow: auto`.

details-height

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

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

function App() {
  return (
    <div style={{ maxWidth: "23rem" }}>
      <Details defaultExpanded>
        <Details.Summary>
          <code>height=&quot;5rem&quot;</code>
        </Details.Summary>
        <Details.Content height="5rem">
          This container scrolls!
          <br />
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details defaultExpanded>
        <Details.Summary>
          <code>height={80}</code>
        </Details.Summary>
        <Details.Content
          height={80}
          style={{ background: "var(--background-color-primary-subdued)" }}
        >
          This container is always <code>80px</code>.
        </Details.Content>
      </Details>
    </div>
  );
}

export default App;
```

details-maxheight

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

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

function App() {
  return (
    <div style={{ maxWidth: "23rem" }}>
      <Details defaultExpanded>
        <Details.Summary>
          <code>maxHeight=&quot;5rem&quot;</code>
        </Details.Summary>
        <Details.Content maxHeight="5rem">
          This container scrolls! <br />
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </Details.Content>
      </Details>
      <Details defaultExpanded>
        <Details.Summary>
          <code>maxHeight={80}</code>
        </Details.Summary>
        <Details.Content maxHeight={80}>
          This container shrinks to fit content under <code>80px</code>.
        </Details.Content>
      </Details>
    </div>
  );
}

export default App;
```

**Details Props**

```tsx theme={null}
<Details defaultExpanded={false} expanded={false}>
  <Details.Summary>Click to expand</Details.Summary>
  <Details.Content>Content here</Details.Content>
</Details>
```

## `Details` Props

**defaultExpanded** `boolean` (default: false)

Controls the default expanded state for uncontrolled details.

**expanded** `boolean` (default: false)

Controls the expanded state for controlled details.

**Details.Content Props**

```tsx theme={null}
<Details.Content height="200px" maxHeight="400px">
  Content here
</Details.Content>
```

## `Details.Content` Props

**height** `string | number`

**maxHeight** `string | number`

**Details.Summary Props**

```tsx theme={null}
<Details.Summary onClick={() => console.log("Clicked")}>
  Click to expand
</Details.Summary>
```

## `Details.Summary` Props

The `Details.Summary` component can accept any valid HTML button props.


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