# BottomSheet

Displays a bottom sheet modal with gesture-based dismissal and snap points support.

## Imports

Note: Before importing this component, ensure you have completed the setup as per the [Quick Start guide](../../../README.md).

```tsx
import {
  BottomSheet,
  useBottomSheet,
  useBottomSheetAnimation,
} from 'heroui-native';
```

## Usage

### Basic Bottom Sheet

Simple bottom sheet with title, description, and close button.

```tsx
<BottomSheet isOpen={isOpen} onOpenChange={setIsOpen}>
  <BottomSheet.Trigger asChild>
    <Button>Open Bottom Sheet</Button>
  </BottomSheet.Trigger>
  <BottomSheet.Portal>
    <BottomSheet.Overlay />
    <BottomSheet.Content>
      <BottomSheet.Close />
      <BottomSheet.Title>...</BottomSheet.Title>
      <BottomSheet.Description>...</BottomSheet.Description>
    </BottomSheet.Content>
  </BottomSheet.Portal>
</BottomSheet>
```

### Detached Bottom Sheet

Bottom sheet that appears detached from the bottom edge with custom spacing.

```tsx
<BottomSheet isOpen={isOpen} onOpenChange={setIsOpen}>
  <BottomSheet.Trigger>...</BottomSheet.Trigger>
  <BottomSheet.Portal>
    <BottomSheet.Overlay />
    <BottomSheet.Content
      detached={true}
      bottomInset={insets.bottom + 12}
      className="mx-4"
      backgroundClassName="rounded-[32px]"
    >
      ...
    </BottomSheet.Content>
  </BottomSheet.Portal>
</BottomSheet>
```

### Scrollable with Snap Points

Bottom sheet with multiple snap points and scrollable content.

```tsx
<BottomSheet isOpen={isOpen} onOpenChange={setIsOpen}>
  <BottomSheet.Trigger>...</BottomSheet.Trigger>
  <BottomSheet.Portal>
    <BottomSheet.Overlay />
    <BottomSheet.Content snapPoints={['25%', '50%', '90%']}>
      <ScrollView>...</ScrollView>
    </BottomSheet.Content>
  </BottomSheet.Portal>
</BottomSheet>
```

### Custom Overlay

Replace the default overlay with custom content like blur effects.

```tsx
import { BottomSheet, useBottomSheetAnimation } from 'heroui-native';
import { StyleSheet } from 'react-native';
import { interpolate, useDerivedValue } from 'react-native-reanimated';
import { AnimatedBlurView } from './animated-blur-view';
import { useUniwind } from 'uniwind';

export const BottomSheetBlurOverlay = () => {
  const { theme } = useUniwind();
  const { progress } = useBottomSheetAnimation();

  const blurIntensity = useDerivedValue(() => {
    return interpolate(progress.get(), [0, 1, 2], [0, 40, 0]);
  });

  return (
    <BottomSheet.Close style={StyleSheet.absoluteFill}>
      <AnimatedBlurView
        blurIntensity={blurIntensity}
        tint={theme === 'dark' ? 'dark' : 'systemUltraThinMaterialDark'}
        style={StyleSheet.absoluteFill}
      />
    </BottomSheet.Close>
  );
};
```

```tsx
<BottomSheet isOpen={isOpen} onOpenChange={setIsOpen}>
  <BottomSheet.Trigger>...</BottomSheet.Trigger>
  <BottomSheet.Portal>
    <BottomSheetBlurOverlay />
    <BottomSheet.Content>...</BottomSheet.Content>
  </BottomSheet.Portal>
</BottomSheet>
```

## Example

```tsx
import { BottomSheet, Button } from 'heroui-native';
import { useState } from 'react';
import { View } from 'react-native';
import { withUniwind } from 'uniwind';
import Ionicons from '@expo/vector-icons/Ionicons';

const StyledIonicons = withUniwind(Ionicons);

export default function BottomSheetExample() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <BottomSheet isOpen={isOpen} onOpenChange={setIsOpen}>
      <BottomSheet.Trigger asChild>
        <Button variant="secondary">Open Bottom Sheet</Button>
      </BottomSheet.Trigger>
      <BottomSheet.Portal>
        <BottomSheet.Overlay />
        <BottomSheet.Content>
          <View className="items-center mb-5">
            <View className="size-20 items-center justify-center rounded-full bg-green-500/10">
              <StyledIonicons
                name="shield-checkmark"
                size={40}
                className="text-green-500"
              />
            </View>
          </View>
          <View className="mb-8 gap-2 items-center">
            <BottomSheet.Title className="text-center">
              Keep yourself safe
            </BottomSheet.Title>
            <BottomSheet.Description className="text-center">
              Update your software to the latest version for better security and
              performance.
            </BottomSheet.Description>
          </View>
          <View className="gap-3">
            <Button onPress={() => setIsOpen(false)}>Update Now</Button>
            <Button variant="tertiary" onPress={() => setIsOpen(false)}>
              Later
            </Button>
          </View>
        </BottomSheet.Content>
      </BottomSheet.Portal>
    </BottomSheet>
  );
}
```

## Anatomy

```tsx
<BottomSheet>
  <BottomSheet.Trigger>...</BottomSheet.Trigger>
  <BottomSheet.Portal>
    <BottomSheet.Overlay>...</BottomSheet.Overlay>
    <BottomSheet.Content>
      <BottomSheet.Close>...</BottomSheet.Close>
      <BottomSheet.Title>...</BottomSheet.Title>
      <BottomSheet.Description>...</BottomSheet.Description>
    </BottomSheet.Content>
  </BottomSheet.Portal>
</BottomSheet>
```

- **BottomSheet**: Root component that manages open state and provides context to child components.
- **BottomSheet.Trigger**: Pressable element that opens the bottom sheet when pressed.
- **BottomSheet.Portal**: Renders bottom sheet content in a portal with full window overlay.
- **BottomSheet.Overlay**: Background overlay that covers the screen, typically closes bottom sheet when pressed.
- **BottomSheet.Content**: Main bottom sheet container using @gorhom/bottom-sheet for rendering with gesture support.
- **BottomSheet.Close**: Close button that dismisses the bottom sheet when pressed.
- **BottomSheet.Title**: Bottom sheet title text with semantic heading role and accessibility linking.
- **BottomSheet.Description**: Bottom sheet description text that provides additional context with accessibility linking.

## API Reference

### BottomSheet

| prop                       | type                       | default | description                                                                                |
| -------------------------- | -------------------------- | ------- | ------------------------------------------------------------------------------------------ |
| `children`                 | `React.ReactNode`          | -       | Bottom sheet content and trigger elements                                                  |
| `isOpen`                   | `boolean`                  | -       | Controlled open state of the bottom sheet                                                  |
| `isDefaultOpen`            | `boolean`                  | `false` | Initial open state when uncontrolled                                                       |
| `closeDelay`               | `number`                   | `300`   | Delay in milliseconds before bottom sheet closes (should match closing animation duration) |
| `isDismissKeyboardOnClose` | `boolean`                  | `true`  | Whether to dismiss keyboard when bottom sheet closes                                       |
| `animation`                | `BottomSheetRootAnimation` | -       | Animation configuration                                                                    |
| `onOpenChange`             | `(value: boolean) => void` | -       | Callback when open state changes                                                           |
| `...ViewProps`             | `ViewProps`                | -       | All standard React Native View props are supported                                         |

#### BottomSheetRootAnimation

Animation configuration for bottom sheet root component. Can be:

- `"disable-all"`: Disable all animations including children
- `undefined`: Use default animations
- `object`: Custom animation configuration

| prop   | type                                    | default | description                                |
| ------ | --------------------------------------- | ------- | ------------------------------------------ |
| `state` | `'disabled' \| 'disable-all' \| boolean` | -       | Disable animations while customizing properties |

### BottomSheet.Trigger

| prop                       | type                    | default | description                                                    |
| -------------------------- | ----------------------- | ------- | -------------------------------------------------------------- |
| `children`                 | `React.ReactNode`       | -       | Trigger element content                                        |
| `asChild`                  | `boolean`               | -       | Render as child element without wrapper                        |
| `...TouchableOpacityProps` | `TouchableOpacityProps` | -       | All standard React Native TouchableOpacity props are supported |

### BottomSheet.Portal

| prop         | type                   | default | description                                      |
| ------------ | ---------------------- | ------- | ------------------------------------------------ |
| `children`   | `React.ReactNode`      | -       | Portal content (overlay and bottom sheet)        |
| `className`  | `string`               | -       | Additional CSS classes for portal container      |
| `style`      | `StyleProp<ViewStyle>` | -       | Additional styles for portal container           |
| `hostName`   | `string`               | -       | Optional portal host name for specific container |
| `forceMount` | `boolean`              | -       | Force mount when closed for animation purposes   |

### BottomSheet.Overlay

| prop                    | type                          | default | description                                                  |
| ----------------------- | ----------------------------- | ------- | ------------------------------------------------------------ |
| `children`              | `React.ReactNode`             | -       | Custom overlay content                                       |
| `className`             | `string`                      | -       | Additional CSS classes for overlay                           |
| `style`                 | `ViewStyle`                   | -       | Additional styles for overlay container                      |
| `animation`             | `BottomSheetOverlayAnimation` | -       | Animation configuration                                      |
| `isAnimatedStyleActive` | `boolean`                     | `true`  | Whether animated styles (react-native-reanimated) are active |
| `isCloseOnPress`        | `boolean`                     | `true`  | Whether pressing overlay closes bottom sheet                 |
| `forceMount`            | `boolean`                     | -       | Force mount when closed for animation purposes               |
| `...PressableProps`     | `PressableProps`              | -       | All standard React Native Pressable props are supported      |

#### BottomSheetOverlayAnimation

Animation configuration for bottom sheet overlay component. Can be:

- `false` or `"disabled"`: Disable all animations
- `true` or `undefined`: Use default animations
- `object`: Custom animation configuration

| prop            | type                          | default     | description                        |
| --------------- | ----------------------------- | ----------- | ---------------------------------- |
| `state`         | `'disabled' \| boolean`       | -           | Disable animations while customizing properties |
| `opacity.value` | `[number, number, number]`     | `[0, 1, 0]` | Opacity values [idle, open, close] |

### BottomSheet.Content

| prop                        | type                                     | default | description                                                                                        |
| --------------------------- | ---------------------------------------- | ------- | -------------------------------------------------------------------------------------------------- |
| `children`                  | `React.ReactNode`                        | -       | Bottom sheet content                                                                               |
| `className`                 | `string`                                 | -       | Additional CSS classes for bottom sheet container                                                  |
| `containerClassName`        | `string`                                 | -       | Additional CSS classes for container                                                               |
| `contentContainerClassName` | `string`                                 | -       | Additional CSS classes for content container                                                       |
| `backgroundClassName`       | `string`                                 | -       | Additional CSS classes for background                                                              |
| `handleClassName`           | `string`                                 | -       | Additional CSS classes for handle                                                                  |
| `handleIndicatorClassName`  | `string`                                 | -       | Additional CSS classes for handle indicator                                                        |
| `contentContainerProps`     | `Omit<BottomSheetViewProps, 'children'>` | -       | Props for the content container                                                                    |
| `animation`                 | `AnimationDisabled`                      | -       | Animation configuration                                                                            |
| `...GorhomBottomSheetProps` | `Partial<GorhomBottomSheetProps>`        | -       | All [@gorhom/bottom-sheet props](https://gorhom.dev/react-native-bottom-sheet/props) are supported |

**Note**: You can use all components from [@gorhom/bottom-sheet](https://gorhom.dev/react-native-bottom-sheet/components/bottomsheetview) inside the content, such as `BottomSheetView`, `BottomSheetScrollView`, `BottomSheetFlatList`, etc.

### BottomSheet.Close

| prop                | type                        | default | description                                             |
| ------------------- | --------------------------- | ------- | ------------------------------------------------------- |
| `children`          | `React.ReactNode`           | -       | Custom close button content                             |
| `className`         | `string`                    | -       | Additional CSS classes for close button                 |
| `iconProps`         | `BottomSheetCloseIconProps` | -       | Configuration for default close icon                    |
| `hitSlop`           | `number`                    | `12`    | Hit slop area for the close button                      |
| `asChild`           | `boolean`                   | -       | Render as child element without wrapper                 |
| `...PressableProps` | `PressableProps`            | -       | All standard React Native Pressable props are supported |

#### BottomSheetCloseIconProps

| prop    | type     | description                             |
| ------- | -------- | --------------------------------------- |
| `size`  | `number` | Icon size (default: 18)                 |
| `color` | `string` | Icon color (default: theme color muted) |

### BottomSheet.Title

| prop           | type              | default | description                                        |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children`     | `React.ReactNode` | -       | Title content                                      |
| `className`    | `string`          | -       | Additional CSS classes for title                   |
| `...TextProps` | `TextProps`       | -       | All standard React Native Text props are supported |

### BottomSheet.Description

| prop           | type              | default | description                                        |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children`     | `React.ReactNode` | -       | Description content                                |
| `className`    | `string`          | -       | Additional CSS classes for description             |
| `...TextProps` | `TextProps`       | -       | All standard React Native Text props are supported |

### useBottomSheet

Hook to access bottom sheet primitive context.

```tsx
const { isOpen, onOpenChange } = useBottomSheet();
```

| property       | type                       | description                   |
| -------------- | -------------------------- | ----------------------------- |
| `isOpen`       | `boolean`                  | Current open state            |
| `onOpenChange` | `(value: boolean) => void` | Function to change open state |

### useBottomSheetAnimation

Hook to access bottom sheet animation context for advanced customization.

```tsx
const { bottomSheetState, progress } = useBottomSheetAnimation();
```

| property           | type                          | description                                  |
| ------------------ | ----------------------------- | -------------------------------------------- |
| `bottomSheetState` | `'idle' \| 'open' \| 'close'` | Internal bottom sheet state                  |
| `progress`         | `SharedValue<number>`         | Animation progress (0=idle, 1=open, 2=close) |
