Docs
Resizable
Resizable
A component that divides your interface into resizable sections.
import {
Resizable,
ResizableHandle,
ResizablePanel,
} from "@repo/tailwindcss/ui/resizable";
const ResizableDemo = () => {
return (
<Resizable class="max-w-md rounded-lg border">
<ResizablePanel initialSize={0.3} minSize={0.2}>
<div class="flex h-[200px] items-center justify-center">
<span class="font-semibold">A</span>
</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel initialSize={0.7} minSize={0.2}>
<Resizable orientation="vertical">
<ResizablePanel initialSize={0.5} minSize={0.2}>
<div class="flex h-full items-center justify-center">
<span class="font-semibold">B</span>
</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel initialSize={0.5} minSize={0.2}>
<div class="flex h-full items-center justify-center">
<span class="font-semibold">C</span>
</div>
</ResizablePanel>
</Resizable>
</ResizablePanel>
</Resizable>
);
};
export default ResizableDemo;
Installation
npx shadcn-solid@latest add resizable
Install the following dependencies:
npm install @corvu/resizable
Copy and paste the following code into your project:
import { cn } from "@/libs/cn";
import type { DynamicProps, HandleProps, RootProps } from "@corvu/resizable";
import ResizablePrimitive from "@corvu/resizable";
import type { ValidComponent, VoidProps } from "solid-js";
import { Show, splitProps } from "solid-js";
export const ResizablePanel = ResizablePrimitive.Panel;
type resizableProps<T extends ValidComponent = "div"> = RootProps<T> & {
class?: string;
};
export const Resizable = <T extends ValidComponent = "div">(
props: DynamicProps<T, resizableProps<T>>,
) => {
const [local, rest] = splitProps(props as resizableProps, ["class"]);
return <ResizablePrimitive class={cn("size-full", local.class)} {...rest} />;
};
type resizableHandleProps<T extends ValidComponent = "button"> = VoidProps<
HandleProps<T> & {
class?: string;
withHandle?: boolean;
}
>;
export const ResizableHandle = <T extends ValidComponent = "button">(
props: DynamicProps<T, resizableHandleProps<T>>,
) => {
const [local, rest] = splitProps(props as resizableHandleProps, [
"class",
"withHandle",
]);
return (
<ResizablePrimitive.Handle
class={cn(
"flex w-px items-center justify-center bg-border transition-shadow focus-visible:outline-none focus-visible:ring-[1.5px] focus-visible:ring-ring focus-visible:ring-offset-1 data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full",
local.class,
)}
{...rest}
>
<Show when={local.withHandle}>
<div class="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-2.5 w-2.5"
viewBox="0 0 15 15"
>
<path
fill="currentColor"
fill-rule="evenodd"
d="M5.5 4.625a1.125 1.125 0 1 0 0-2.25a1.125 1.125 0 0 0 0 2.25m4 0a1.125 1.125 0 1 0 0-2.25a1.125 1.125 0 0 0 0 2.25M10.625 7.5a1.125 1.125 0 1 1-2.25 0a1.125 1.125 0 0 1 2.25 0M5.5 8.625a1.125 1.125 0 1 0 0-2.25a1.125 1.125 0 0 0 0 2.25m5.125 2.875a1.125 1.125 0 1 1-2.25 0a1.125 1.125 0 0 1 2.25 0M5.5 12.625a1.125 1.125 0 1 0 0-2.25a1.125 1.125 0 0 0 0 2.25"
clip-rule="evenodd"
/>
<title>Resizable handle</title>
</svg>
</div>
</Show>
</ResizablePrimitive.Handle>
);
};
Install the following dependencies:
npm install @corvu/resizable
Copy and paste the following code into your project:
import { cn } from "@/libs/cn";
import type { DynamicProps, HandleProps, RootProps } from "@corvu/resizable";
import ResizablePrimitive from "@corvu/resizable";
import type { ValidComponent, VoidProps } from "solid-js";
import { Show, splitProps } from "solid-js";
export const ResizablePanel = ResizablePrimitive.Panel;
type resizableProps<T extends ValidComponent = "div"> = RootProps<T> & {
class?: string;
};
export const Resizable = <T extends ValidComponent = "div">(
props: DynamicProps<T, resizableProps<T>>,
) => {
const [local, rest] = splitProps(props as resizableProps, ["class"]);
return <ResizablePrimitive class={cn("size-full", local.class)} {...rest} />;
};
type resizableHandleProps<T extends ValidComponent = "button"> = VoidProps<
HandleProps<T> & {
class?: string;
withHandle?: boolean;
}
>;
export const ResizableHandle = <T extends ValidComponent = "button">(
props: DynamicProps<T, resizableHandleProps<T>>,
) => {
const [local, rest] = splitProps(props as resizableHandleProps, [
"class",
"withHandle",
]);
return (
<ResizablePrimitive.Handle
class={cn(
"flex w-px items-center justify-center bg-border focus-visible:(outline-none ring-1.5 ring-ring ring-offset-1) data-[orientation=vertical]:(h-px w-full) transition-shadow",
local.class,
)}
{...rest}
>
<Show when={local.withHandle}>
<div class="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-2.5 w-2.5"
viewBox="0 0 15 15"
>
<path
fill="currentColor"
fill-rule="evenodd"
d="M5.5 4.625a1.125 1.125 0 1 0 0-2.25a1.125 1.125 0 0 0 0 2.25m4 0a1.125 1.125 0 1 0 0-2.25a1.125 1.125 0 0 0 0 2.25M10.625 7.5a1.125 1.125 0 1 1-2.25 0a1.125 1.125 0 0 1 2.25 0M5.5 8.625a1.125 1.125 0 1 0 0-2.25a1.125 1.125 0 0 0 0 2.25m5.125 2.875a1.125 1.125 0 1 1-2.25 0a1.125 1.125 0 0 1 2.25 0M5.5 12.625a1.125 1.125 0 1 0 0-2.25a1.125 1.125 0 0 0 0 2.25"
clip-rule="evenodd"
/>
<title>Resize handle</title>
</svg>
</div>
</Show>
</ResizablePrimitive.Handle>
);
};
Usage
import { Resizable, ResizablePanel, ResizableHandle } from "@/components/ui/resizable";
<Resizable>
<ResizablePanel>A</ResizablePanel>
<ResizableHandle />
<ResizablePanel>B</ResizablePanel>
</Resizable>
Examples
Vertical
Use the orientation
prop to set the orientation of the resizable panels.
import {
Resizable,
ResizableHandle,
ResizablePanel,
} from "@repo/tailwindcss/ui/resizable";
const ResizableVerticalDemo = () => {
return (
<Resizable
orientation="vertical"
class="h-[200px] max-w-md rounded-lg border"
>
<ResizablePanel initialSize={0.3} minSize={0.2}>
<div class="flex h-full items-center justify-center">
<span class="font-semibold">A</span>
</div>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel initialSize={0.7} minSize={0.2}>
<div class="flex h-full items-center justify-center">
<span class="font-semibold">B</span>
</div>
</ResizablePanel>
</Resizable>
);
};
export default ResizableVerticalDemo;
Handle
You can set or hide the handle by using the withHandle
prop on the ResizableHandle
component.
import {
Resizable,
ResizableHandle,
ResizablePanel,
} from "@repo/tailwindcss/ui/resizable";
const ResizableWithHandleDemo = () => {
return (
<Resizable class="min-h-[200px] max-w-md rounded-lg border">
<ResizablePanel initialSize={0.3} minSize={0.2}>
<div class="flex h-full items-center justify-center">
<span class="font-semibold">A</span>
</div>
</ResizablePanel>
<ResizableHandle withHandle />
<ResizablePanel initialSize={0.7} minSize={0.2}>
<div class="flex h-full items-center justify-center">
<span class="font-semibold">B</span>
</div>
</ResizablePanel>
</Resizable>
);
};
export default ResizableWithHandleDemo;