# Popover (React Native)

> A panel anchored to its trigger, placed with the same maths as the web Popover.

GramproKit for React Native · Overlays · Beta · Source: https://kit.gramproindia.com/native/docs/popover

> **Beta:** React Native support is in beta. APIs may change or break between prereleases (npm tag `native`).

_Interactive demo:_ [open the live example](https://kit.gramproindia.com/native/docs/popover). The example's source:

```tsx
import { useState } from "react";
import { Text, View } from "react-native";
import { Button } from "@/component-lib/button";
import { Popover } from "@/component-lib/popover";
import { useKitTheme } from "@/component-lib/shared/native";
import { Row, Section } from "./layout"; // Section and Row: page layout for the demo

export function PopoverDemo() {
  const { tokens } = useKitTheme();
  const [reason, setReason] = useState("—");
  return (
    <>
      <Section title="Popover · anchored">
        <Row>
          <Popover
            trigger={<Button variant="outline">Help</Button>}
            title="What is GST?"
            description="Goods and Services Tax, charged on most sales in India."
            onOpenChange={(open, why) => setReason(open ? "opened" : (why ?? "?"))}
          >
            Your invoices show it per line, at the rate set on each product.
          </Popover>
          <Popover trigger={<Button variant="outline">Filters</Button>} aria-label="Filters" side="bottom" align="end">
            {({ close }) => (
              <View style={{ gap: 10 }}>
                <Text style={{ color: tokens.fg }}>Only unpaid invoices</Text>
                <Button size="sm" onPress={close}>
                  Apply
                </Button>
              </View>
            )}
          </Popover>
        </Row>
        <Text style={{ color: tokens.muted }}>Last close reason: {reason}</Text>
      </Section>

      <Section title="Popover · as a sheet">
        <Popover
          presentation="sheet"
          trigger={<Button variant="secondary">Share settings</Button>}
          title="Share settings"
          description="People with the link can view this invoice."
        >
          The link expires in 7 days. Revoke it any time from Settings.
        </Popover>
      </Section>
    </>
  );
}
```

## Install

```bash
npx @grampro/kit@native add Popover
```

## Usage

```tsx
import { Popover } from "@/component-lib/popover";

<Popover trigger={<Button variant="outline">Details</Button>} title="GST">
  <Text>18% on services.</Text>
</Popover>
```

## Props

### PopoverProps

| Prop | Type | Description |
|---|---|---|
| `trigger` (required) | `ReactElement<TriggerProps>` | The element that opens it, cloned with a ref (to measure where it is) and an `onPress`. Any Kit button, or any Pressable, works. |
| `children` | `ReactNode \| ((props: PopoverRenderProps) => ReactNode)` |   |
| `open` | `boolean` | Controlled open state. |
| `defaultOpen` | `boolean` | Open to begin with, when you are not controlling `open`. |
| `onOpenChange` | `(open: boolean, reason?: PopoverCloseReason) => void` | `reason` is `outside` (tap outside or Android back), `trigger` or `api`, and undefined when opening. |
| `title` | `ReactNode` | Heading inside the panel, which also names it. |
| `description` | `ReactNode` | A line under the title. |
| `side` | `PopoverSide` | Side of the trigger to open on, before flipping for space. Default `bottom`. |
| `align` | `PopoverAlign` | Default `start`. |
| `gap` | `number` | Distance from the trigger, in dp. Default 6. |
| `scrollable` | `boolean` | Cap the panel to the space available and let it scroll. Default false. |
| `presentation` | `"auto" \| "popover" \| "sheet"` | `popover` anchors it to the trigger (default); `sheet` opens a bottom sheet; `auto` picks a sheet on phones and a popover on tablets. |
| `style` | `StyleProp<ViewStyle>` | The panel's style (the web's `className` on the panel). |
| `styles` | `Partial<{ panel: StyleProp<ViewStyle>; header: StyleProp<ViewStyle>; title: StyleProp<T…` |   |
| `localeText` | `Partial<PopoverLocaleText>` |   |

## Native and web

- Android back and a tap outside both close with reason `outside`.
- Web version: [Popover on the web](https://kit.gramproindia.com/popover).
