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
Preview
Section titled “Preview”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>- Slots —
triggeris 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 tobottom-start. The panel flips and shifts to stay on screen.- Controlled — omit
openfor click-to-toggle, or set theopenproperty and drive it fromkai-open-changeto 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-smand inherits from there). Use your own icon library for chevrons and row icons.
| Slot | Mode | Purpose |
|---|---|---|
| (default) | inject | The popover panel body. The control that opens it is the `trigger` slot. |
| trigger | replace | The control that opens the popover (a button, an avatar, …). The panel anchors to it. |
| Property | Type | Default | Notes |
|---|---|---|---|
| theme | "light" | "dark" | "auto" | 'auto' | Color mode (`auto` follows prefers-color-scheme). |
| placement | 'bottom-start' | Floating placement relative to the trigger (floating-ui placement). | |
| gutter | number | 6 | Gap in px between the trigger and the panel. |
| open | boolean | — | Drive/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`. |
| defaultOpen | boolean | — | Initial open state on mount (uncontrolled seed). |
| disabled | boolean | — | Turn the popover off while keeping the trigger mounted (clicks and `show()` no longer open it). |
Events
Section titled “Events”| Event | Detail | Notes |
|---|---|---|
| kai-open-change | | The popover opened or closed (click, Escape, outside-click, or a method). |
Methods
Section titled “Methods”| Method | Signature | Notes |
|---|---|---|
| show | (): void | Open it programmatically (no-op while disabled). |
| hide | (): void | Close it programmatically. |
| toggle | (): void | Flip the open state (closes while disabled). |
Composed from
Section titled “Composed from”This element wraps these SolidJS components — reach for them directly when you need finer control than the props expose.
Popover