Zmienny rozmiar
Przesuwalne, dzielone okna do edytorów kodu, drzew plików i układów pulpitów nawigacyjnych — z neobrutalistycznymi ramkami i cieniami.
import {
ResizableHandle,
ResizablePanel,Komponent resizable dzieli obszar na panele, których proporcje użytkownik zmienia przeciąganiem — w poziomie lub w pionie, z możliwością zagnieżdżania i z uchwytami obsługiwanymi z klawiatury. Oba warianty opakowują bibliotekę react-resizable-panels autorstwa bvaughn, ostylowaną zgodnie z neobrutalistyczną recepturą: grube ramki, twarde cienie i wyrazista typografia.
Sięgnij po to rozwiązanie, gdy:
- Edytory kodu i układy w stylu IDE — drzewo plików, edytor i panel podglądu, których rozmiary użytkownicy dopasowują do własnych potrzeb.
- Widoki master–detail — skrzynka odbiorcza i wątek, tabela i inspektor rekordu, z linią podziału tam, gdzie chce jej użytkownik.
- Pulpity nawigacyjne i konsole — pozwól panelowi logów lub terminalowi odebrać wysokość głównemu widokowi bez otwierania okna modalnego.
O komponencie#
Komponent Resizable jest oparty na react-resizable-panels autorstwa bvaughn.
Instalacja#
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
Zainstaluj następujące zależności:
pnpm add react-resizable-panelsnpm install react-resizable-panelsyarn add react-resizable-panelsbun add react-resizable-panels
Skopiuj i wklej poniższy kod do swojego projektu.
"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 }
Zaktualizuj ścieżki importu, aby pasowały do konfiguracji twojego projektu.
Użycie#
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"<ResizablePanelGroup orientation="horizontal">
<ResizablePanel>One</ResizablePanel>
<ResizableHandle />
<ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>Kompozycja#
Użyj poniższej kompozycji, aby zbudować ResizablePanelGroup:
ResizablePanelGroup
├── ResizablePanel
├── ResizableHandle
└── ResizablePanelPrzykłady#
Pionowy#
Użyj orientation="vertical" do zmiany rozmiaru w pionie.
import {
ResizableHandle,
ResizablePanel,Uchwyt#
Użyj propa withHandle na ResizableHandle, aby pokazać widoczny uchwyt.
import {
ResizableHandle,
ResizablePanel,RTL#
Aby włączyć obsługę RTL w Neobrutalism, zobacz przewodnik konfiguracji RTL.
"use client"
import * as React from "react"Dostępność#
Uchwyt realizuje wzorzec WAI-ARIA Window Splitter: react-resizable-panels renderuje każdy uchwyt jako fokusowalny element role="separator" z aria-valuenow / aria-valuemin / aria-valuemax oraz aria-controls wskazującym panel, którego rozmiar zmienia — dzięki temu czytniki ekranu na bieżąco ogłaszają położenie podziału.
Obsługa klawiatury:
| Klawisz | Działanie |
|---|---|
Tab / Shift + Tab | Przenosi fokus na uchwyt zmiany rozmiaru / poza niego |
ArrowLeft / ArrowRight | Zmienia rozmiar paneli w grupie poziomej o jeden krok |
ArrowUp / ArrowDown | Zmienia rozmiar paneli w grupie pionowej o jeden krok |
Home | Zmniejsza panel przed uchwytem do rozmiaru minimalnego |
End | Powiększa panel przed uchwytem do rozmiaru maksymalnego |
Enter | Przełącza panel zwijany między stanem zwiniętym a rozwiniętym |
Referencja API#
Zobacz dokumentację react-resizable-panels.
Lista zmian#
2025-02-02 react-resizable-panels v4#
Zaktualizowano do react-resizable-panels v4. Zobacz informacje o wydaniu v4.0.0, aby poznać pełne szczegóły.
Jeśli używasz prymitywów react-resizable-panels bezpośrednio, zwróć uwagę na następujące zmiany:
| 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 |
Komponenty opakowujące Neobrutalism (ResizablePanelGroup, ResizablePanel,
ResizableHandle) pozostają bez zmian.