Größenveränderbar
Verschiebbare geteilte Fenster für Code-Editoren, Dateibäume und Dashboard-Layouts – mit dem neobrutalistischen Design aus Rahmen und Schatten.
import {
ResizableHandle,
ResizablePanel,Die Resizable-Komponente teilt einen Bereich in Panels, deren Größenverhältnis Nutzer per Ziehen anpassen – horizontal oder vertikal, verschachtelbar, mit per Tastatur bedienbaren Handles. Beide Varianten kapseln react-resizable-panels von bvaughn und folgen dem neobrutalistischen Rezept: dicke Rahmen, harte Schatten und kräftige Typografie.
Typische Anwendungsfälle:
- Code-Editoren und IDE-artige Layouts – Dateibaum, Editor und Vorschau, die Nutzer nach eigenem Geschmack dimensionieren.
- Master-Detail-Ansichten – Posteingang und Thread, Tabelle und Datensatz-Inspektor, mit dem Teiler genau dort, wo ihn die Nutzer haben wollen.
- Dashboards und Konsolen – ein Log-Bereich oder Terminal darf der Hauptansicht Höhe abnehmen, ganz ohne Modal.
Über#
Die Komponente Resizable basiert auf react-resizable-panels von bvaughn.
Installation#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/resizable.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/resizable.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/resizable.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/resizable.json
Installiere die folgenden Abhängigkeiten:
pnpm add react-resizable-panelsnpm install react-resizable-panelsyarn add react-resizable-panelsbun add react-resizable-panels
Kopiere den folgenden Code und füge ihn in dein Projekt ein.
"use client"
import * as ResizablePrimitive from "react-resizable-panels"
import { cn } from "@/lib/utils"
function ResizablePanelGroup({
className,
...props
}: ResizablePrimitive.GroupProps) {
return (
<ResizablePrimitive.Group
data-slot="resizable-panel-group"
className={cn(
"flex h-full w-full aria-[orientation=vertical]:flex-col",
className
)}
{...props}
/>
)
}
function ResizablePanel({ ...props }: ResizablePrimitive.PanelProps) {
return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />
}
function ResizableHandle({
withHandle,
className,
...props
}: ResizablePrimitive.SeparatorProps & {
withHandle?: boolean
}) {
return (
<ResizablePrimitive.Separator
data-slot="resizable-handle"
className={cn(
"relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90",
className
)}
{...props}
>
{withHandle && (
<div className="z-10 flex h-6 w-1 shrink-0 rounded-lg bg-border" />
)}
</ResizablePrimitive.Separator>
)
}
export { ResizableHandle, ResizablePanel, ResizablePanelGroup }
Passe die Importpfade an dein Projekt-Setup an.
Verwendung#
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"<ResizablePanelGroup orientation="horizontal">
<ResizablePanel>One</ResizablePanel>
<ResizableHandle />
<ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>Komposition#
Verwende die folgende Komposition, um eine ResizablePanelGroup aufzubauen:
ResizablePanelGroup
├── ResizablePanel
├── ResizableHandle
└── ResizablePanelBeispiele#
Vertikal#
Verwende orientation="vertical" für eine vertikale Größenänderung.
import {
ResizableHandle,
ResizablePanel,Griff#
Verwende die Prop withHandle an ResizableHandle, um einen sichtbaren Griff anzuzeigen.
import {
ResizableHandle,
ResizablePanel,RTL#
Um RTL-Unterstützung in Neobrutalism zu aktivieren, sieh dir die RTL-Konfigurationsanleitung an.
"use client"
import * as React from "react"Barrierefreiheit#
Das Handle folgt dem WAI-ARIA-Pattern „Window Splitter“: react-resizable-panels rendert jedes Handle als fokussierbares Element mit role="separator", aria-valuenow / aria-valuemin / aria-valuemax sowie einem aria-controls, das auf das jeweils veränderte Panel zeigt – Screenreader kündigen die Position der Teilung daher bei jeder Änderung an.
Tastaturinteraktionen:
| Taste | Aktion |
|---|---|
Tab / Shift + Tab | Bewegt den Fokus auf ein Resize-Handle bzw. von ihm weg |
ArrowLeft / ArrowRight | Passt eine horizontale Gruppe um einen Schritt an |
ArrowUp / ArrowDown | Passt eine vertikale Gruppe um einen Schritt an |
Home | Verkleinert das Panel vor dem Handle auf seine Minimalgröße |
End | Vergrößert das Panel vor dem Handle auf seine Maximalgröße |
Enter | Schaltet ein einklappbares Panel zwischen ein- und ausgeklappt um |
API-Referenz#
Sieh dir die Dokumentation von react-resizable-panels an.
Changelog#
2025-02-02 react-resizable-panels v4#
Aktualisiert auf react-resizable-panels v4. Alle Details findest du in den Release Notes zu v4.0.0.
Wenn du die Primitives von react-resizable-panels direkt verwendest, beachte die folgenden Änderungen:
| v3 | v4 |
|---|---|
PanelGroup | Group |
PanelResizeHandle | Separator |
direction prop | orientation prop |
defaultSize={50} | defaultSize="50%" |
onLayout | onLayoutChange |
ImperativePanelHandle | PanelImperativeHandle |
ref prop on Panel | panelRef prop |
data-panel-group-direction | aria-orientation |
Die Wrapper-Komponenten von Neobrutalism (ResizablePanelGroup, ResizablePanel,
ResizableHandle) bleiben unverändert.