# Popover

> Documentation and examples for adding custom Bootstrap popovers with content and positioning.

Source: https://bootstrap-svelte.vercel.app/components/popover — part of the Bootstrap Svelte documentation (index: https://bootstrap-svelte.vercel.app/llms.txt).

---

## Basic Example

The Popover component creates a small overlay that appears when a user clicks, hovers, or focuses on an element. It consists of several components that work together: `Popover.Root`, `Popover.Header`, and `Popover.Body`.

```html
<Button id="basic-popover-button" colorVariant="primary">
    Click for Popover
</Button>

<Popover.Root isShown={isPopoverShown} referenceElementId="basic-popover-button">
    <Popover.Header>Popover Title</Popover.Header>
    <Popover.Body>
        <p>This is the popover body content. It can contain various elements.</p>
    </Popover.Body>
</Popover.Root>
```

## Triggers

Popovers can be triggered in different ways: `click`, `hover`, `focus`, or a combination of them. The default trigger is `click`.

```html
<!-- Click trigger (default) -->
<Button id="click-popover-button" colorVariant="secondary">
    Click me
</Button>

<Popover.Root referenceElementId="click-popover-button" trigger="click">
    <Popover.Header>Click Triggered</Popover.Header>
    <Popover.Body>
        <p>This popover is activated by clicking on the button.</p>
    </Popover.Body>
</Popover.Root>

<!-- Hover trigger -->
<Button id="hover-popover-button" colorVariant="secondary">
    Hover me
</Button>

<Popover.Root referenceElementId="hover-popover-button" trigger="hover">
    <Popover.Header>Hover Triggered</Popover.Header>
    <Popover.Body>
        <p>This popover is activated by hovering over the button.</p>
    </Popover.Body>
</Popover.Root>

<!-- Focus trigger -->
<Button id="focus-popover-button" colorVariant="secondary">
    Focus me
</Button>

<Popover.Root referenceElementId="focus-popover-button" trigger="focus">
    <Popover.Header>Focus Triggered</Popover.Header>
    <Popover.Body>
        <p>This popover is activated by focusing on the button.</p>
    </Popover.Body>
</Popover.Root>

<!-- Multiple triggers -->
<Button id="multi-trigger-popover-button" colorVariant="secondary">
    Hover or focus me
</Button>

<Popover.Root referenceElementId="multi-trigger-popover-button" trigger="hover focus">
    <Popover.Header>Multiple Triggers</Popover.Header>
    <Popover.Body>
        <p>This popover is triggered by either hovering or focusing.</p>
    </Popover.Body>
</Popover.Root>
```

## Placement Options

Popovers can be placed in various positions relative to their reference element: `top`, `right`, `bottom`, `left`, or `auto`. The default placement is `right`.

```html
<!-- Top placement -->
<Button id="top-popover-button" colorVariant="secondary">
    Popover on top
</Button>

<Popover.Root referenceElementId="top-popover-button" placement="top">
    <Popover.Header>Top Placed</Popover.Header>
    <Popover.Body>
        <p>This popover appears at the top.</p>
    </Popover.Body>
</Popover.Root>

<!-- Right placement (default) -->
<Button id="right-popover-button" colorVariant="secondary">
    Popover on right
</Button>

<Popover.Root referenceElementId="right-popover-button" placement="right">
    <Popover.Header>Right Placed</Popover.Header>
    <Popover.Body>
        <p>This popover appears on the right.</p>
    </Popover.Body>
</Popover.Root>

<!-- Bottom placement -->
<Button id="bottom-popover-button" colorVariant="secondary">
    Popover on bottom
</Button>

<Popover.Root referenceElementId="bottom-popover-button" placement="bottom">
    <Popover.Header>Bottom Placed</Popover.Header>
    <Popover.Body>
        <p>This popover appears at the bottom.</p>
    </Popover.Body>
</Popover.Root>

<!-- Left placement -->
<Button id="left-popover-button" colorVariant="secondary">
    Popover on left
</Button>

<Popover.Root referenceElementId="left-popover-button" placement="left">
    <Popover.Header>Left Placed</Popover.Header>
    <Popover.Body>
        <p>This popover appears on the left.</p>
    </Popover.Body>
</Popover.Root>

<!-- Auto placement -->
<Button id="auto-popover-button" colorVariant="secondary">
    Popover with auto placement
</Button>

<Popover.Root referenceElementId="auto-popover-button" placement="auto">
    <Popover.Header>Auto Placed</Popover.Header>
    <Popover.Body>
        <p>This popover uses automatic placement based on available space.</p>
    </Popover.Body>
</Popover.Root>
```

## Dismissible Popover

You can make popovers dismissible by adding a close button or other interactive element inside the popover body. Use the `onHidden` event to update your state when the popover is dismissed.

```html
<Button id="dismissible-popover-button" colorVariant="primary" onclick={() => isDismissiblePopoverShown = true}>
    Click for Dismissible Popover
</Button>

<Popover.Root isShown={isDismissiblePopoverShown} referenceElementId="dismissible-popover-button" onHidden={() => isDismissiblePopoverShown = false}>
    <Popover.Header>Dismissible Popover</Popover.Header>
    <Popover.Body>
        <p>This popover can be closed by clicking the button below.</p>
        <div class="mt-2 d-flex justify-content-end">
            <Button colorVariant="secondary" size="sm" onclick={() => isDismissiblePopoverShown = false}>Close</Button>
        </div>
    </Popover.Body>
</Popover.Root>
```

## Remove Animation

For popovers that should appear and disappear without a fade animation, set the `useFade` property to `false`.

```html
<Button id="no-fade-popover-button" colorVariant="primary" onclick={() => isNoFadePopoverShown = true}>
    Popover without fade
</Button>

<Popover.Root isShown={isNoFadePopoverShown} useFade={false} referenceElementId="no-fade-popover-button" onHidden={() => isNoFadePopoverShown = false}>
    <Popover.Header>No Fade Effect</Popover.Header>
    <Popover.Body>
        <p>This popover appears and disappears without a fade animation.</p>
        <div class="mt-2 d-flex justify-content-end">
            <Button colorVariant="secondary" size="sm" onclick={() => isNoFadePopoverShown = false}>Close</Button>
        </div>
    </Popover.Body>
</Popover.Root>
```

## Custom Header

You can customize the header element by changing its level (h1-h6) using the `level` prop or by adding CSS classes.

```html
<Button id="custom-header-popover-button" colorVariant="secondary">
    Custom Header Level
</Button>

<Popover.Root referenceElementId="custom-header-popover-button">
    <Popover.Header level={1}>H1 Title</Popover.Header>
    <Popover.Body>
        <p>This popover uses an h1 for the header instead of the default h3.</p>
    </Popover.Body>
</Popover.Root>

<!-- With custom styling -->
<Button id="custom-styled-header-popover-button" colorVariant="secondary">
    Custom Styled Header
</Button>

<Popover.Root referenceElementId="custom-styled-header-popover-button">
    <Popover.Header class="text-danger">Red Title</Popover.Header>
    <Popover.Body>
        <p>This popover has a red header.</p>
    </Popover.Body>
</Popover.Root>
```

## HTML Content

Popovers can contain rich HTML content, including lists, form elements, or interactive components.

```html
<Button id="html-content-popover-button" colorVariant="primary" onclick={() => isHtmlContentShown = true}>
    Popover with HTML content
</Button>

<Popover.Root isShown={isHtmlContentShown} referenceElementId="html-content-popover-button" onHidden={() => isHtmlContentShown = false}>
    <Popover.Header>Rich Content</Popover.Header>
    <Popover.Body>
        <p>Popovers can contain <strong>rich</strong> <em>HTML</em> content.</p>
        <ul class="mb-0">
            <li>List items</li>
            <li>Form elements</li>
            <li>And more!</li>
        </ul>
        <div class="mt-2 d-flex justify-content-between">
            <Button colorVariant="outline-primary" size="sm">Action</Button>
            <Button colorVariant="outline-secondary" size="sm" onclick={() => isHtmlContentShown = false}>Close</Button>
        </div>
    </Popover.Body>
</Popover.Root>
```

## Disabled Elements

When you need to show a popover on a disabled button, you'll encounter an issue: disabled buttons don't trigger mouse or keyboard events. To work around this, wrap the disabled button in a `<span>` element with `tabindex="0"` to make it focusable, then attach the popover to the span instead.

```html
<!-- Using a span wrapper with tabindex to enable popover on disabled button -->
<span id="disabled-button-wrapper" tabindex="0" style="display: inline-block; cursor: not-allowed;">
    <Button disabled>Disabled Button</Button>
</span>

<Popover.Root referenceElementId="disabled-button-wrapper" trigger="hover focus">
    <Popover.Header>Disabled Button Popover</Popover.Header>
    <Popover.Body>
        <p>This popover works with a disabled button by using a span wrapper with tabindex="0".</p>
    </Popover.Body>
</Popover.Root>
```

## Component API

### Popover.Root Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `class` | `string` | - | Additional CSS classes to apply to the component |
| `container` | `string \| HTMLElement \| false` | `false` | Specifies where to append the popover in the DOM. Default is `false` (appends to body). |
| `elementRef` | `HTMLElement \| null` | `null` | Reference to the DOM element |
| `id` | `string` | Auto-generated | Unique identifier for the offcanvas |
| `isShown` | `boolean` | `false` | Controls whether the popover is visible. |
| `onHide` | `function` | | Callback to invoke when the popover starts hiding. |
| `onHidden` | `function` | | Callback to invoke when the popover has been hidden. |
| `onShow` | `function` | | Callback to invoke when the popover starts showing. |
| `onShown` | `function` | | Callback to invoke when the popover has been shown. |
| `placement` | `'top' \| 'right' \| 'bottom' \| 'left' \| 'auto'` | `'right'` | Where to position the popover relative to the reference element. |
| `referenceElementId` | `string` | | The ID of the element that the popover should be positioned relative to. It accommodates the id containing a hash or not. |
| `trigger` | `'click' \| 'hover' \| 'focus' \| 'manual'` | `'click'` | How the popover is triggered. Can be space-separated for multiple triggers. The use of `'manual'` indicates that the popover will be triggered programmatically via the `isShown` property. |
| `useFade` | `boolean` | `true` | Controls whether the popover uses a fade transition. |

### Popover.Header Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `level` | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | `3` | The heading level to use (h1-h6). |

### CSS Classes

These classes can be used to customize the popover components:

| Class | Applied to | Description |
| --- | --- | --- |
| `.popover` | Popover.Root | Main container for the popover. |
| `.popover-header` | Popover.Header | Styles the popover title. |
| `.popover-body` | Popover.Body | Styles the popover content. |
| `.bs-popover-top` | Popover.Root | Applied when the popover is placed at the top. |
| `.bs-popover-end` | Popover.Root | Applied when the popover is placed on the right. |
| `.bs-popover-bottom` | Popover.Root | Applied when the popover is placed at the bottom. |
| `.bs-popover-start` | Popover.Root | Applied when the popover is placed on the left. |
| `.fade` | Popover.Root | Applies fade transition effect. |
| `.show` | Popover.Root | Makes the popover visible. |
