Skip to content
kitn AI/UI

Popover

kai-popover

A trigger that toggles a floating card of arbitrary content — a model menu, a settings panel, an account dropdown. The panel is a role="dialog" region, not a menu, so it holds anything: rows, toggles, nested groups. Click a position around the trigger below to see each placement.

  • Shadow DOM
  • 1 event
  • Slotted trigger + panel
  • Escape / outside-click close
  • 12 placements

Slot the control as slot="trigger" and the panel as the default slot:

<kai-popover placement="bottom-start">
<button slot="trigger">GPT-5.5 ▾</button>
<div>
<button>GPT-5.5 — Flagship model</button>
<button>Legacy models ▾</button>
<label>Temporary chat <kai-switch label="Temporary chat"></kai-switch></label>
</div>
</kai-popover>
<script type="module">
import '@kitn.ai/ui/elements';
document.querySelector('kai-popover')
.addEventListener('kai-open-change', (e) => console.log('open:', e.detail.open));
</script>
  • Slotstrigger is the control; the default slot is the panel. Clicking the trigger toggles it.
  • Dismissal — Escape or a click outside closes the panel; clicks inside it do not.
  • placement — floating placement relative to the trigger (bottom-start, top, right, …); defaults to bottom-start. The panel flips and shifts to stay on screen.
  • Controlled — omit open for click-to-toggle, or set the open property and drive it from kai-open-change to control it yourself.
  • Panel content lives in your light DOM, so your own styles apply to it directly — no shadow piercing. Font size, spacing, icons are all yours: style the slotted content however you like (the panel defaults to a compact text-sm and inherits from there). Use your own icon library for chevrons and row icons.
SlotModePurpose
injectThe popover panel body. The control that opens it is the `trigger` slot.
replaceThe control that opens the popover (a button, an avatar, …). The panel anchors to it.
PropertyTypeDefaultNotes
theme'auto'Color mode (`auto` follows prefers-color-scheme).
placement'bottom-start'Floating placement relative to the trigger (floating-ui placement).
gutter6Gap in px between the trigger and the panel.
openDrive/observe open state (Shoelace-style: settable + reflected to the `open` attribute, the element still self-manages on click). Set `el.open = true`, or `<kai-popover open>`; listen for `kai-open-change`.
defaultOpenInitial open state on mount (uncontrolled seed).
disabledTurn the popover off while keeping the trigger mounted (clicks and `show()` no longer open it).
EventDetailNotes
The popover opened or closed (click, Escape, outside-click, or a method).
MethodSignatureNotes
(): voidOpen it programmatically (no-op while disabled).
(): voidClose it programmatically.
(): voidFlip the open state (closes while disabled).

This element wraps these SolidJS components — reach for them directly when you need finer control than the props expose.

Popover