Resizable

Panels with drag handles between them.

import { … } from '@inlaylab/ivorie/resizable'
One
Two
Three
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_RESIZABLE_IMPORTS } from '@inlaylab/ivorie/resizable';

@Component({
  selector: 'demo-resizable',
  imports: [IV_RESIZABLE_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-resizable-panel-group class="max-w-md rounded-lg border md:min-w-[450px]">
      <iv-resizable-panel defaultSize="50">
        <div class="flex h-[200px] items-center justify-center p-6"><span class="font-semibold">One</span></div>
      </iv-resizable-panel>
      <iv-resizable-handle />
      <iv-resizable-panel defaultSize="50">
        <iv-resizable-panel-group orientation="vertical">
          <iv-resizable-panel defaultSize="25">
            <div class="flex h-full items-center justify-center p-6"><span class="font-semibold">Two</span></div>
          </iv-resizable-panel>
          <iv-resizable-handle />
          <iv-resizable-panel defaultSize="75">
            <div class="flex h-full items-center justify-center p-6"><span class="font-semibold">Three</span></div>
          </iv-resizable-panel>
        </iv-resizable-panel-group>
      </iv-resizable-panel>
    </iv-resizable-panel-group>
  `,
})
export default class ResizableDemo {}

Installation

CLInpm
npx ivorie add resizable

Sizes are percent of the group. Drag a handle, or focus it and use the arrow keys.

Usage

import { IV_RESIZABLE_IMPORTS } from '@inlaylab/ivorie/resizable';
<iv-resizable-panel-group class="rounded-lg border">
  <iv-resizable-panel defaultSize="30" minSize="20">One</iv-resizable-panel>
  <iv-resizable-handle />
  <iv-resizable-panel>Two</iv-resizable-panel>
</iv-resizable-panel-group>

Examples

Handle

Sidebar
Content
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_RESIZABLE_IMPORTS } from '@inlaylab/ivorie/resizable';

@Component({
  selector: 'demo-resizable-handle',
  imports: [IV_RESIZABLE_IMPORTS],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <iv-resizable-panel-group class="min-h-[200px] max-w-md rounded-lg border md:min-w-[450px]">
      <iv-resizable-panel defaultSize="25" minSize="15">
        <div class="flex h-full items-center justify-center p-6"><span class="font-semibold">Sidebar</span></div>
      </iv-resizable-panel>
      <iv-resizable-handle [withHandle]="true" />
      <iv-resizable-panel defaultSize="75">
        <div class="flex h-full items-center justify-center p-6"><span class="font-semibold">Content</span></div>
      </iv-resizable-panel>
    </iv-resizable-panel-group>
  `,
})
export default class ResizableHandleDemo {}

API

Every part also accepts class.

iv-resizable-panel-group

Name Type Default Description
orientation 'horizontal' | 'vertical' 'horizontal' Direction panels are laid out in.

Output: layoutChange (number[]): sizes in percent after a drag or key press.

iv-resizable-panel

Name Type Default Description
defaultSize number equal share Start size in percent.
minSize number 0 Smallest size in percent.
maxSize number 100 Largest size in percent.

iv-resizable-handle

Name Type Default Description
withHandle boolean false Shows a grip.
aria-label string | null 'Resize' Label for the handle.

Accessibility

Each handle is a focusable separator with its value in percent. Arrow keys move it.