Popover

Displays rich content triggered by a button.

Usage

Basecoat popovers are inline-positioned relative to the .popover wrapper. This differs from shadcn/ui's portalled Base UI implementation, but keeps the markup dependency-free and works with Basecoat's existing dropdown/select positioning model.

HTML + JavaScript

Step 1: Include the JavaScript file

You can either include the JavaScript file for all the components, or just the one for this component by adding this to the <head> of your page:

<script src="https://cdn.jsdelivr.net/npm/basecoat-css@1.0.0/dist/js/basecoat.min.js" defer></script>
<script src="https://cdn.jsdelivr.net/npm/basecoat-css@1.0.0/dist/js/popover.min.js" defer></script>

Step 2: Add your popover HTML

<div id="demo-popover" class="popover">
  <button id="demo-popover-trigger" type="button" aria-expanded="false" aria-controls="demo-popover-popover" class="btn-outline">Open popover</button>
  <div id="demo-popover-popover" data-popover aria-hidden="true" class="w-72">
    <header>
      <h4>Dimensions</h4>
      <p>Set the dimensions for the layer.</p>
    </header>
    <form class="grid gap-2">
      <div class="grid grid-cols-3 items-center gap-4">
        <label for="demo-popover-width">Width</label>
        <input type="text" id="demo-popover-width" value="100%" class="input col-span-2 h-8" autofocus />
      </div>
      <div class="grid grid-cols-3 items-center gap-4">
        <label for="demo-popover-max-width">Max. width</label>
        <input type="text" id="demo-popover-max-width" value="300px" class="input col-span-2 h-8" />
      </div>
      <div class="grid grid-cols-3 items-center gap-4">
        <label for="demo-popover-height">Height</label>
        <input type="text" id="demo-popover-height" value="25px" class="input col-span-2 h-8" />
      </div>
      <div class="grid grid-cols-3 items-center gap-4">
        <label for="demo-popover-max-height">Max. height</label>
        <input type="text" id="demo-popover-max-height" value="none" class="input col-span-2 h-8" />
      </div>
    </form>
  </div>
</div>

HTML structure

<div class="popover">
Relative wrapper for the trigger and inline popover content.
<button type="button" aria-expanded="false" aria-controls="{ POPOVER_ID }">
Trigger button. The script toggles aria-expanded and opens/closes the content.
<div data-popover id="{ POPOVER_ID }" aria-hidden="true">
Popover content. Set data-side="top|right|bottom|left" and data-align="start|center|end" to control placement.
<header> Optional
Header area. A heading inside the header is styled as the popover title, and a paragraph is styled as the description.

JavaScript events

basecoat:initialized
Once the component is initialized, it dispatches a custom non-bubbling basecoat:initialized event on itself.
basecoat:popover
When the popover opens, the component dispatches a custom event on document. Other popover-based components listen for this to close any open popovers.

Jinja and Nunjucks

You can use the popover() Nunjucks or Jinja macro for this component.

{% call popover(
  id="demo-popover",
  trigger="Open popover",
  trigger_attrs={"class": "btn-outline"},
  popover_attrs={"class": "w-72", "data-align": "center"}
) %}
  <header>
    <h4>Title</h4>
    <p>Description text here.</p>
  </header>
{% endcall %}

Examples

Basic

Align

With Form

RTL

Popover alignment uses logical start and end offsets. Set dir="rtl" on a parent to flip start/end alignment.

API Reference

.popover
Root wrapper. Must contain the trigger button and direct [data-popover] content.
[data-popover]
Popover content. Supports data-side, data-align, and aria-hidden.
data-side
Placement side: top, right, bottom, or left. Defaults to bottom.
data-align
Alignment: start, center, or end. Defaults to start.