One
Two
Three
<script lang="ts">
import * as Resizable from "$lib/components/ui/resizable/index.js";
</script>
<Resizable.PaneGroup direction="horizontal" class="max-w-md rounded-lg border">
<Resizable.Pane defaultSize={50}>
<div class="flex h-[200px] items-center justify-center p-6">
<span class="font-semibold">One</span>
</div>
</Resizable.Pane>
<Resizable.Handle />
<Resizable.Pane defaultSize={50}>
<Resizable.PaneGroup direction="vertical">
<Resizable.Pane defaultSize={25}>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Two</span>
</div>
</Resizable.Pane>
<Resizable.Handle />
<Resizable.Pane defaultSize={75}>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Three</span>
</div>
</Resizable.Pane>
</Resizable.PaneGroup>
</Resizable.Pane>
</Resizable.PaneGroup> About
The Resizable component is built on top of PaneForge by Huntabyte. Visit the PaneForge documentation for all the available props and abilities of the Resizable component.
Installation
pnpm dlx shadcn-svelte@latest add resizable Install paneforge:
pnpm add paneforge@next -D Copy and paste the following code into your project.
import { Pane } from 'paneforge';
import Handle from './resizable-handle.svelte';
import PaneGroup from './resizable-pane-group.svelte';
export {
PaneGroup,
Pane,
Handle,
//
PaneGroup as ResizablePaneGroup,
Pane as ResizablePane,
Handle as ResizableHandle
};
<script lang="ts">
import * as ResizablePrimitive from 'paneforge';
import { cn, type WithoutChildrenOrChild } from '$UTILS$.js';
let {
ref = $bindable(null),
class: className,
withHandle = false,
...restProps
}: WithoutChildrenOrChild<ResizablePrimitive.PaneResizerProps> & {
withHandle?: boolean;
} = $props();
</script>
<ResizablePrimitive.PaneResizer
bind:ref
data-slot="resizable-handle"
class={cn(
'cn-resizable-handle relative flex w-px items-center justify-center bg-zinc-800 after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-zinc-300 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[direction=vertical]:h-px data-[direction=vertical]:w-full data-[direction=vertical]:after:left-0 data-[direction=vertical]:after:h-1 data-[direction=vertical]:after:w-full data-[direction=vertical]:after:translate-x-0 data-[direction=vertical]:after:-translate-y-1/2 [&[data-direction=vertical]>div]:rotate-90',
className
)}
{...restProps}
>
{#if withHandle}
<div class="z-10 flex h-6 w-1 shrink-0 rounded-none bg-[#b9d765]"></div>
{/if}
</ResizablePrimitive.PaneResizer>
<script lang="ts">
import * as ResizablePrimitive from 'paneforge';
import { cn } from '$UTILS$.js';
let {
ref = $bindable(null),
this: paneGroup = $bindable(),
class: className,
...restProps
}: ResizablePrimitive.PaneGroupProps & {
this?: ResizablePrimitive.PaneGroup;
} = $props();
</script>
<ResizablePrimitive.PaneGroup
bind:ref
bind:this={paneGroup}
data-slot="resizable-pane-group"
class={cn(
'cn-resizable-panel-group flex h-full w-full border border-zinc-800 bg-background text-zinc-100 data-[direction=vertical]:flex-col',
className
)}
{...restProps}
/>
Usage
<script lang="ts">
import * as Resizable from '$lib/components/ui/resizable/index.js';
</script> <Resizable.PaneGroup direction="horizontal">
<Resizable.Pane>One</Resizable.Pane>
<Resizable.Handle />
<Resizable.Pane>Two</Resizable.Pane>
</Resizable.PaneGroup> Examples
Vertical
Use the direction prop to set the direction of the resizable panels.
Header
Content
<script lang="ts">
import * as Resizable from "$lib/components/ui/resizable/index.js";
</script>
<Resizable.PaneGroup
direction="vertical"
class="min-h-[200px] max-w-md rounded-lg border"
>
<Resizable.Pane defaultSize={25}>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Header</span>
</div>
</Resizable.Pane>
<Resizable.Handle />
<Resizable.Pane defaultSize={75}>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Content</span>
</div>
</Resizable.Pane>
</Resizable.PaneGroup> <script lang="ts">
import * as Resizable from '$lib/components/ui/resizable/index.js';
</script>
<Resizable.PaneGroup direction="vertical">
<Resizable.Pane>One</Resizable.Pane>
<Resizable.Handle />
<Resizable.Pane>Two</Resizable.Pane>
</Resizable.PaneGroup> Handle
You can set or hide the handle by using the withHandle prop on the ResizableHandle component.
Sidebar
Content
<script lang="ts">
import * as Resizable from "$lib/components/ui/resizable/index.js";
</script>
<Resizable.PaneGroup
direction="horizontal"
class="min-h-[200px] max-w-md rounded-lg border"
>
<Resizable.Pane defaultSize={25}>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Sidebar</span>
</div>
</Resizable.Pane>
<Resizable.Handle withHandle />
<Resizable.Pane defaultSize={75}>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Content</span>
</div>
</Resizable.Pane>
</Resizable.PaneGroup> <script lang="ts">
import * as Resizable from '$lib/components/ui/resizable/index.js';
</script>
<Resizable.PaneGroup direction="vertical">
<Resizable.Pane>One</Resizable.Pane>
<Resizable.Handle withHandle />
<Resizable.Pane>Two</Resizable.Pane>
</Resizable.PaneGroup>