Docs Components Primitives

Resizable

React example follows below.
ts
const resizableFixture = {
id: "resizable",
defaultSize: 50,
className: "h-[200px] w-full",
first: { label: "Editor", body: "Drag the handle to split." },
second: {
label: "Preview",
className: "bg-sunken",
body: "Arrow keys nudge the handle when focused.",
},
} satisfies {
id: string;
defaultSize: number;
className: string;
first: { label: string; body: string };
second: { label: string; className: string; body: string };
};
import { Resizable, ResizablePanel } from "@grassroot/ui-react";
export default function ResizableDemo() {
return (
<div>
<Resizable defaultSize={resizableFixture.defaultSize} className={resizableFixture.className}>
<ResizablePanel label={resizableFixture.first.label}>
{resizableFixture.first.body}
</ResizablePanel>
<ResizablePanel
label={resizableFixture.second.label}
className={resizableFixture.second.className}
>
{resizableFixture.second.body}
</ResizablePanel>
</Resizable>
</div>
);
}
ts
<script setup lang="ts">
const resizableFixture = {
id: "resizable",
defaultSize: 50,
className: "h-[200px] w-full",
first: { label: "Editor", body: "Drag the handle to split." },
second: {
label: "Preview",
className: "bg-sunken",
body: "Arrow keys nudge the handle when focused.",
},
} satisfies {
id: string;
defaultSize: number;
className: string;
first: { label: string; body: string };
second: { label: string; className: string; body: string };
};
import { Resizable, ResizablePanel } from "@grassroot/ui-vue";
</script>
<template>
<div>
<Resizable :default-size="resizableFixture.defaultSize" :class="resizableFixture.className">
<template #first>
<ResizablePanel :label="resizableFixture.first.label">{{
resizableFixture.first.body
}}</ResizablePanel>
</template>
<template #second>
<ResizablePanel
:label="resizableFixture.second.label"
:class="resizableFixture.second.className"
>
{{ resizableFixture.second.body }}
</ResizablePanel>
</template>
</Resizable>
</div>
</template>
ts
import { Component } from "@angular/core";
const resizableFixture = {
id: "resizable",
defaultSize: 50,
className: "h-[200px] w-full",
first: { label: "Editor", body: "Drag the handle to split." },
second: {
label: "Preview",
className: "bg-sunken",
body: "Arrow keys nudge the handle when focused.",
},
} satisfies {
id: string;
defaultSize: number;
className: string;
first: { label: string; body: string };
second: { label: string; className: string; body: string };
};
import { GrassrootResizable, GrassrootResizablePanel } from "@grassroot/ui-angular";
@Component({
selector: "app-resizable-demo",
standalone: true,
imports: [GrassrootResizable, GrassrootResizablePanel],
template: `
<div>
<grassroot-resizable [defaultSize]="fixture.defaultSize" [class]="fixture.className">
<grassroot-resizable-panel first [label]="fixture.first.label">{{
fixture.first.body
}}</grassroot-resizable-panel>
<grassroot-resizable-panel
second
[label]="fixture.second.label"
[class]="fixture.second.className"
>
{{ fixture.second.body }}
</grassroot-resizable-panel>
</grassroot-resizable>
</div>
`,
})
export class ResizableDemoComponent {
protected readonly fixture = resizableFixture;
}
export default ResizableDemoComponent;
ts
<script lang="ts">
import { Resizable, ResizablePanel } from "@grassroot/ui-svelte";
const resizableFixture = {
id: "resizable",
defaultSize: 50,
className: "h-[200px] w-full",
first: { label: "Editor", body: "Drag the handle to split." },
second: {
label: "Preview",
className: "bg-sunken",
body: "Arrow keys nudge the handle when focused.",
},
} satisfies {
id: string;
defaultSize: number;
className: string;
first: { label: string; body: string };
second: { label: string; className: string; body: string };
};
</script>
<div>
<Resizable defaultSize={resizableFixture.defaultSize} className={resizableFixture.className}>
{#snippet first()}
<ResizablePanel label={resizableFixture.first.label}
>{resizableFixture.first.body}</ResizablePanel
>
{/snippet}
{#snippet second()}
<ResizablePanel
label={resizableFixture.second.label}
className={resizableFixture.second.className}
>
{resizableFixture.second.body}
</ResizablePanel>
{/snippet}
</Resizable>
</div>
ts
/** @jsxImportSource solid-js */
const resizableFixture = {
id: "resizable",
defaultSize: 50,
className: "h-[200px] w-full",
first: { label: "Editor", body: "Drag the handle to split." },
second: {
label: "Preview",
className: "bg-sunken",
body: "Arrow keys nudge the handle when focused.",
},
} satisfies {
id: string;
defaultSize: number;
className: string;
first: { label: string; body: string };
second: { label: string; className: string; body: string };
};
import { Resizable, ResizablePanel } from "@grassroot/ui-solid";
export default function ResizableDemo() {
return (
<div>
<Resizable defaultSize={resizableFixture.defaultSize} className={resizableFixture.className}>
<ResizablePanel label={resizableFixture.first.label}>
{resizableFixture.first.body}
</ResizablePanel>
<ResizablePanel
label={resizableFixture.second.label}
className={resizableFixture.second.className}
>
{resizableFixture.second.body}
</ResizablePanel>
</Resizable>
</div>
);
}

Installation

API Reference

Import

import { Resizable, ResizablePanel } from "@grassroot/ui-react";

Props

Prop
Type
Default
Requirement
Description
direction
"horizontal" | "vertical" | undefined
"horizontal"
optional
Split direction.
defaultSize
number | undefined
50
optional
Initial size of the first pane, in %.
minSize
number | undefined
12
optional
Minimum size of either pane, in %.
step
number | undefined
4
optional
Keyboard nudge step, in %.
onResize
((size: number) => void) | undefined
optional
Notified after each resize, with the first pane's new %.
Prop
direction
Type
"horizontal" | "vertical" | undefined
Default
"horizontal"
Requirement
optional
Description
Split direction.
Prop
defaultSize
Type
number | undefined
Default
50
Requirement
optional
Description
Initial size of the first pane, in %.
Prop
minSize
Type
number | undefined
Default
12
Requirement
optional
Description
Minimum size of either pane, in %.
Prop
step
Type
number | undefined
Default
4
Requirement
optional
Description
Keyboard nudge step, in %.
Prop
onResize
Type
((size: number) => void) | undefined
Default
Requirement
optional
Description
Notified after each resize, with the first pane's new %.

Events

EventPayload
onResize((size: number) => void) | undefined

Content regions

  • children

Native attributes

Standard DOM and ARIA attributes not listed above spread onto the root element.

Import

import { Resizable, ResizablePanel } from "@grassroot/ui-vue";

Props

Prop
Type
Default
Requirement
direction
"horizontal" | "vertical" | undefined
"horizontal"
optional
defaultSize
number | undefined
50
optional
minSize
number | undefined
12
optional
step
number | undefined
4
optional
Prop
direction
Type
"horizontal" | "vertical" | undefined
Default
"horizontal"
Requirement
optional
Prop
defaultSize
Type
number | undefined
Default
50
Requirement
optional
Prop
minSize
Type
number | undefined
Default
12
Requirement
optional
Prop
step
Type
number | undefined
Default
4
Requirement
optional

Events

EventPayload
resize[size: number]

Content regions

  • first
  • second

Import

import { Component } from "@angular/core";
import { GrassrootResizable, GrassrootResizablePanel } from "@grassroot/ui-angular";

Props

Prop
Type
Default
Requirement
direction
"horizontal" | "vertical"
"horizontal"
optional
defaultSize
number
50
optional
minSize
number
12
optional
step
number
4
optional
Prop
direction
Type
"horizontal" | "vertical"
Default
"horizontal"
Requirement
optional
Prop
defaultSize
Type
number
Default
50
Requirement
optional
Prop
minSize
Type
number
Default
12
Requirement
optional
Prop
step
Type
number
Default
4
Requirement
optional

Events

EventPayload
resizenumber

Content regions

  • first
  • second

Import

import { Resizable, ResizablePanel } from "@grassroot/ui-svelte";

Props

Prop
Type
Default
Requirement
direction
"horizontal" | "vertical"
"horizontal"
optional
defaultSize
number
50
optional
minSize
number
12
optional
step
number
4
optional
onResize
(size: number) => void
optional
className
string
optional
Prop
direction
Type
"horizontal" | "vertical"
Default
"horizontal"
Requirement
optional
Prop
defaultSize
Type
number
Default
50
Requirement
optional
Prop
minSize
Type
number
Default
12
Requirement
optional
Prop
step
Type
number
Default
4
Requirement
optional
Prop
onResize
Type
(size: number) => void
Default
Requirement
optional
Prop
className
Type
string
Default
Requirement
optional

Events

EventPayload
onResize(size: number) => void

Content regions

  • children
  • first
  • second

Import

import { Resizable, ResizablePanel } from "@grassroot/ui-solid";

Props

Prop
Type
Default
Requirement
direction
"horizontal" | "vertical"
optional
defaultSize
number
optional
minSize
number
optional
step
number
optional
onResize
(size: number) => void
optional
className
string
optional
Prop
direction
Type
"horizontal" | "vertical"
Default
Requirement
optional
Prop
defaultSize
Type
number
Default
Requirement
optional
Prop
minSize
Type
number
Default
Requirement
optional
Prop
step
Type
number
Default
Requirement
optional
Prop
onResize
Type
(size: number) => void
Default
Requirement
optional
Prop
className
Type
string
Default
Requirement
optional

Events

EventPayload
onResize(size: number) => void

Content regions

  • children

Native attributes

Standard DOM and ARIA attributes not listed above spread onto the root element.