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

# Bottom Sheet - React Native

> The BottomSheet provides a bottom-anchored modal surface for general content.

> [!NOTE]
>
> For development, import `BottomSheet` from
> `@servicetitan/anvil2-rn`. For design, find it in the
> [Mobile Agentic Component Library file](https://www.figma.com/design/gjGWnAOnI1kukfzjsUQ6dP/Mobile-Agentic-Component-Library).

**Implementation**

```tsx theme={null}
import { BottomSheet, Button } from "@servicetitan/anvil2-rn";

function App() {
  return (
    <BottomSheet
      title="Quick actions"
      content="Review these actions before you continue."
      trigger={<Button label="Open sheet" variant="secondary" />}
    />
  );
}
```

## Common Examples

To use the `BottomSheet`, pass the required `title` and `content`. Open it with an Anvil2 RN `Button` through `trigger`, or control it with `isOpen` and `onOpenChange`.

```tsx theme={null}
import { BottomSheet, Button } from "@servicetitan/anvil2-rn";

function ExampleComponent() {
  return (
    <BottomSheet
      title="Filters"
      trigger={<Button label="Open filters" />}
      content={<FilterForm />}
    />
  );
}
```

### Body content

Unlike `Dialog`, the sheet's `content` is a general body region for forms, lists, and composed layouts. A plain string still renders in the sheet's body typography. The header stays pinned while the body scrolls.

### Subheader

Pass a short `subheader` for context beneath the title.

```tsx theme={null}
<BottomSheet
  title="Job #48213"
  subheader="Scheduled for tomorrow at 9:00 AM"
  content="Review the job details before confirming the appointment."
  trigger={<Button label="Open sheet" variant="secondary" />}
/>
```

### Open state

Omit `isOpen` for an uncontrolled sheet. Seed it with `defaultOpen`. When you pass `isOpen`, `onOpenChange` is required so the header close, scrim, Android back, and drag-to-dismiss can request a close.

```tsx theme={null}
const [isOpen, setOpen] = useState(false);

<BottomSheet
  title="Filters"
  content={<FilterForm />}
  isOpen={isOpen}
  onOpenChange={setOpen}
/>
```

Set `isDismissable={false}` to keep the scrim and Android back from closing the sheet. The header close still dismisses when `showCloseButton` is true.

## Accessibility

* The required `title` is a heading that names the modal. The sheet sets `accessibilityViewIsModal`.
* The header close control is a button named `"Close"` (English until the kit gains i18n).
* Drag down on the handle, tap the scrim, or use Android back to dismiss when `isDismissable` is true.
* Reduce motion skips the slide animation.

**BottomSheet Props**

```tsx theme={null}
<BottomSheet
  title="Filters"
  subheader="Narrow your results"
  trigger={<Button label="Open filters" />}
  content={<FilterForm />}
  showCloseButton
/>
```

## `BottomSheet` Props

The `BottomSheet` accepts the following props. It does not forward remaining React Native `Modal` or `View` props. Open state is a discriminated union: pass `isOpen` with `onOpenChange`, or omit `isOpen` for the uncontrolled form.

**content** `ReactNode` *required*

General body content, including forms, lists, and composed layout.

**title** `string` *required*

Accessible title rendered in the header.

**analyticsId** `string`

Opt-in telemetry id. When set under `Anvil2RNTelemetryProvider`, the
header close, scrim, and Android back emit a `dismiss` event.

**defaultOpen** `boolean`

Whether the sheet starts open when uncontrolled. Unavailable when
`isOpen` is set.

**isDismissable** `boolean` (default: true)

Whether tapping the scrim or using Android back closes the sheet.

**isOpen** `boolean`

Controlled open state. Pair with `onOpenChange`.

**onOpenChange** `(isOpen: boolean) =\> void`

Called when the open state changes. Required when `isOpen` is set.

**showCloseButton** `boolean` (default: true)

Shows the header close button.

**subheader** `string`

Short secondary line beneath the title.

**testID** `string`

Test hook forwarded to the sheet surface.

**trigger** `ReactElement\<ButtonProps\>`

Anvil2 RN `Button` that opens the sheet. Omit for controlled state.


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