Skip to content
kitn AI/UI

Resizable

kai-resizable

Compose a draggable multi-panel shell — sidebar + chat, list + inspector, three-up — by placing <kai-resizable-item> children inside; dividers, drag logic, keyboard resize, and expand-to-fill are handled for you.

  • Shadow DOM
  • 2 events
  • Up to 3 panels (nest for more)
  • px or % sizing
  • Expand-to-fill protocol
<kai-resizable orientation="horizontal" style="display:block;height:400px">
<kai-resizable-item size="25%" min="160px"> <!-- list panel --> </kai-resizable-item>
<kai-resizable-item> <!-- chat panel, fills remaining space --> </kai-resizable-item>
<kai-resizable-item size="30%"> <!-- preview panel --> </kai-resizable-item>
</kai-resizable>
<script type="module">
import '@kitn.ai/ui/elements';
document.querySelector('kai-resizable')
.addEventListener('kai-change', (e) => console.log(e.detail.sizes));
</script>
  • size — initial main-axis size: "280px" or "25%". Omit for a flexible panel that fills remaining space.
  • min / max — resize bounds in px or %, e.g. min="140px" or max="50%".
  • locked — fixes the panel; adjacent dividers become non-draggable separators.
  • hidden — removes the panel and its divider; remaining panels reflow. Toggle at runtime to collapse/restore.
  • maximizedIndex — set this property to the zero-based panel index to maximize it (null to restore). Or call el.maximize(n) / el.restore() imperatively.

Expand-to-fill — when a <kai-artifact expandable> fires kai-maximize-intent (bubbling, composed), the nearest enclosing <kai-resizable> catches it automatically and hides siblings. No wiring needed. Escape or Collapse restores the layout.

Wire <kai-artifact expandable> inside an item — pressing Expand maximizes that panel automatically:

<kai-resizable orientation="horizontal" style="display:block;height:480px">
<kai-resizable-item size="20%" min="120px"> …list… </kai-resizable-item>
<kai-resizable-item min="140px"> …chat… </kai-resizable-item>
<kai-resizable-item size="35%" min="200px">
<kai-artifact src="…/index.html" expandable></kai-artifact>
</kai-resizable-item>
</kai-resizable>
<script type="module">
import '@kitn.ai/ui/elements';
const r = document.querySelector('kai-resizable');
r.addEventListener('kai-change', (e) => console.log('sizes', e.detail.sizes));
r.addEventListener('kai-maximize-change', (e) => console.log(e.detail));
// r.restore(); or r.maximizedIndex = null;
</script>
SlotModePurpose
injectThe `<kai-resizable-item>` panels, in order. Dividers are inserted between them.
PropertyTypeDefaultNotes
theme'auto'Color mode (`auto` follows prefers-color-scheme).
orientation'horizontal'Layout axis: `horizontal` (row, default) or `vertical` (column).
maximizedIndexnullWhich item index is maximized (null = none). Declarative source of truth.
handle'line'Divider affordance drawn inside each draggable handle's 8px grab zone: - `line` (default): a 1px hairline, transparent at rest, tinting on hover/drag. - `grip`: a dotted grip handle. - `none`: no visible divider, just the invisible hit-area. The full grab zone and keyboard/ARIA behavior are identical for all three.
EventDetailNotes
Fired on drag-end / keyboard resize / visibility change. `detail.sizes` = panel sizes in percent.
Observe layout maximize state.
Authoritative maximize state, dispatched as a raw composed CustomEvent (not through `dispatch`) onto the affected `<kai-resizable-item>` and, on restore, onto the group host. A nested element (e.g. `<kai-artifact>`) listens for it to reconcile its own toggle.
MethodSignatureNotes
(index: number): voidImperatively maximize the item at `index` (thin wrapper over `maximizedIndex`).
(): voidImperatively restore from the maximized layout.

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

ResizableHandle