kai-lightbox
Opens the media above the page and restores focus to the trigger when it closes.
- Shadow DOM
- Click or keyboard
- Escape + backdrop close
- Focus trapped
Preview
Section titled “Preview”Put the trigger as the default light content and the media in slot="content". A click or Enter/Space on the trigger opens the modal; the element fires kai-open-change and exposes show(), hide() and toggle() for a host that drives it from somewhere else.
<kai-lightbox label="Sunset over the bay"> <img src="/thumb.jpg" alt="" width="96" height="96" /> <img slot="content" src="/full.jpg" alt="Sunset over the bay" /></kai-lightbox>Set open (or default-open) to drive it yourself and leave the trigger slot empty. An empty trigger renders no button at all, so a host that owns the open state does not ship a dead tab stop.
<kai-lightbox open label="Architecture diagram"> <img slot="content" src="/diagram.svg" alt="Architecture diagram" /></kai-lightbox>The modal carries its own close (X) button in the panel’s top-right corner, on by default — it is the affordance a pointer user looks for first, and it reports through kai-open-change like Escape and the backdrop. Pass show-close="false" when the trigger or a host control already dismisses the modal, and style it with kai-lightbox::part(close).
A click anywhere inside the content dismisses the modal too, also on by default: every photo viewer closes on a click on the picture. A click that lands on something interactive inside the content — a link in a caption, a download button beside the media — is let through, so those keep working, and the panel’s own padding does not close it either. Pass close-on-content-click="false" when a click inside the content means something else, such as toggling a zoom level; Escape, a backdrop click and hide() still dismiss the modal.
Examples
Section titled “Examples”A thumbnail that opens
Section titled “A thumbnail that opens”The tile holds a small image; the modal holds the same image at the size the viewport allows. The media is clamped to 85vh/90vw, so a tall or a wide file fits without scrolling.
Driven by the host
Section titled “Driven by the host”show() and hide() are the imperative pair for a control that lives outside the element, and kai-open-change reports every transition.
<kai-button id="open">Open the diagram</kai-button><kai-lightbox id="box" label="Architecture diagram"> <img slot="content" src="/diagram.svg" alt="Architecture diagram" /></kai-lightbox><script> const box = document.getElementById('box'); document.getElementById('open').addEventListener('click', () => box.show()); box.addEventListener('kai-open-change', (e) => console.log(e.detail.open));</script>| Slot | Mode | Purpose |
|---|---|---|
| (default) | inject | The TRIGGER the modal opens from: plain markup of your own, and optional. With nothing here the element renders no button and you drive it from `show()` or the `open` attribute. The zoomed media is the `content` slot. |
| content | replace | The media the modal shows; the default slot is the trigger. |
| Property | Type | Default | Notes |
|---|---|---|---|
| theme | "light" | "dark" | "auto" | 'auto' | Color mode (`auto` follows prefers-color-scheme). |
| open | boolean | — | Drive/observe the open state: `el.open = true` or the bare `open` attribute. Listen for `kai-open-change`. |
| defaultOpen | boolean | — | Initial open state on mount (uncontrolled seed). |
| disabled | boolean | — | Take away the PROGRAMMATIC open path only: `show()` becomes a no-op and `toggle()` closes rather than opens. |
| label | string | — | Accessible name for the modal (`aria-label`). Name it: an unnamed `role="dialog"` is a WCAG failure. |
| showClose | boolean | true | Show the close (X) button in the modal's top-right corner. Default `true`. |
| closeOnContentClick | boolean | true | Close the modal on a click inside `slot="content"`. Default `true`. |
Events
Section titled “Events”| Event | Detail | Notes |
|---|---|---|
| kai-open-change | | The modal opened or closed (trigger click, Escape, backdrop 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.