# Pop

**`sonic-pop`** anchors a floating panel to a trigger: put the control in the default slot and the panel (menu, form, any markup) in **`slot="content"`**. A click on the trigger toggles the panel unless **`manual`** is set. The panel follows the trigger while open and flips to stay inside the viewport.

## Basic example

<sonic-code>
  <template>
    <sonic-pop>
      <sonic-button>Notifications</sonic-button>
      <sonic-menu slot="content">
        <sonic-menu-item>
          <sonic-icon library="iconoir" name="bell-notification" slot="prefix"></sonic-icon>
          Notifications
        </sonic-menu-item>
        <sonic-menu-item>
          <sonic-icon library="iconoir" name="settings" slot="prefix"></sonic-icon>
          Settings
        </sonic-menu-item>
      </sonic-menu>
    </sonic-pop>
  </template>
</sonic-code>

## Placement

**`placement`** is a side (`top` · `bottom` · `left` · `right`) with an optional alignment suffix (`-start` · `-center` · `-end`). Default is `bottom`; without a suffix, the panel aligns to `start`. The space syntax (`bottom center`) is deprecated.

<sonic-code>
  <template>
    <div class="flex flex-wrap gap-2">
      <sonic-pop placement="top">
        <sonic-button>Top</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
      <sonic-pop placement="bottom">
        <sonic-button>Bottom</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
      <sonic-pop placement="left">
        <sonic-button>Left</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
      <sonic-pop placement="right">
        <sonic-button>Right</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
      <sonic-pop placement="top-center">
        <sonic-button>Top center</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
      <sonic-pop placement="bottom-center">
        <sonic-button>Bottom center</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
      <sonic-pop placement="left-center">
        <sonic-button>Left center</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
      <sonic-pop placement="bottom-end">
        <sonic-button>Bottom end</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
    </div>
  </template>
</sonic-code>

## Shadow

The panel shadow defaults to `lg`.

<sonic-code>
  <template>
    <div class="flex flex-wrap gap-2">
      <sonic-pop shadow="none">
        <sonic-button>None</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
      <sonic-pop shadow="sm">
        <sonic-button>Small</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
      <sonic-pop shadow="md">
        <sonic-button>Medium</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
      <sonic-pop shadow="lg">
        <sonic-button>Large</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
    </div>
  </template>
</sonic-code>

## Inline

The host is middle-aligned by default. Set **`inline`** to baseline-align a trigger inside running text.

<sonic-code>
  <template>
    <p>
      You are signed in as
      <sonic-pop inline>
        <sonic-button variant="link">ada.lindqvist@example.com</sonic-button>
        <sonic-menu slot="content">
          <sonic-menu-item>Profile</sonic-menu-item>
          <sonic-menu-item>Sign out</sonic-menu-item>
        </sonic-menu>
      </sonic-pop>
      on this device.
    </p>
  </template>
</sonic-code>

## No toggle

With **`noToggle`**, clicking the trigger opens the pop but does not close it. Close it with an outside click, Escape or **`hide()`**.

<sonic-code>
  <template>
    <div class="flex flex-wrap gap-2">
      <sonic-pop noToggle>
        <sonic-button>No toggle</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
      <sonic-pop>
        <sonic-button>Default toggle</sonic-button>
        <sonic-menu slot="content"><sonic-menu-item>Item</sonic-menu-item></sonic-menu>
      </sonic-pop>
    </div>
  </template>
</sonic-code>

## Manual control

**`manual`** disables the built-in click and keyboard handling on the trigger. Call **`show()`** and **`hide()`** instead.

<sonic-code>
  <template>
    <sonic-pop manual id="manualPop">
      <sonic-button onclick="alert('Custom action, the pop stays closed')">Manual trigger</sonic-button>
      <sonic-menu slot="content">
        <sonic-menu-item>Opened from script</sonic-menu-item>
      </sonic-menu>
    </sonic-pop>
    <sonic-button onclick="document.getElementById('manualPop').show()" class="ml-5" variant="outline">
      Open the pop
    </sonic-button>
  </template>
</sonic-code>

## Keep open on select

A click inside the panel closes the pop by default. Set **`data-on-select="keep"`** on the panel or a descendant to keep it open, for example while ticking checkboxes.

<sonic-code>
  <template>
    <div class="flex flex-wrap gap-2">
      <sonic-pop>
        <sonic-button>Closes on select</sonic-button>
        <div slot="content" class="grid gap-2 p-3">
          <sonic-checkbox>Window seat</sonic-checkbox>
          <sonic-checkbox>Extra baggage</sonic-checkbox>
        </div>
      </sonic-pop>
      <sonic-pop>
        <sonic-button>Stays open on select</sonic-button>
        <div slot="content" class="grid gap-2 p-3" data-on-select="keep">
          <sonic-checkbox>Window seat</sonic-checkbox>
          <sonic-checkbox>Extra baggage</sonic-checkbox>
        </div>
      </sonic-pop>
    </div>
  </template>
</sonic-code>

## Keyboard

**ArrowDown** on the trigger opens the pop. **Escape** closes the most recently opened pop, before an enclosing `sonic-modal`, and returns focus to its trigger.

<sonic-code>
  <template>
    <sonic-pop>
      <sonic-button>Focus me, then press ArrowDown</sonic-button>
      <sonic-menu slot="content">
        <sonic-menu-item>First item</sonic-menu-item>
        <sonic-menu-item>Second item</sonic-menu-item>
      </sonic-menu>
    </sonic-pop>
  </template>
</sonic-code>

## API reference

| Attribute | Values | Description |
|----------|---------|-------------|
| `placement` | `top` · `bottom` (default) · `left` · `right`, each with optional `-start` · `-center` · `-end` | Side and alignment relative to the trigger |
| `shadow` | `none` · `sm` · `md` · `lg` (default `lg`) | Panel shadow |
| `inline` | boolean | Baseline-align the host in text |
| `noToggle` | boolean | A trigger click does not close an open pop |
| `manual` | boolean | Disable trigger click and keyboard handling |

| Slot | Description |
|------|-------------|
| *(default)* | Trigger |
| `content` | Floating panel; `data-on-select="keep"` inside it prevents close on click |

| Method | Description |
|--------|-------------|
| `show()` | Open the panel |
| `hide()` | Close the panel |

| Event | Description |
|-------|-------------|
| `show` | Panel opened |
| `hide` | Panel closed |
