Ridimensionabile
Riquadri divisibili trascinabili per editor di codice, alberi di file e layout di dashboard — con lo stile neobrutalista caratterizzato da bordi e ombre.
import {
ResizableHandle,
ResizablePanel,Il componente resizable divide una regione in pannelli che l’utente trascina per riproporzionare — in orizzontale o in verticale, annidabili, con maniglie utilizzabili da tastiera. Entrambe le varianti avvolgono react-resizable-panels di bvaughn, rifinite secondo la ricetta neobrutalista: bordi spessi, ombre nette e tipografia in grassetto.
Quando usarlo:
- Editor di codice e layout in stile IDE — albero dei file, editor e pannelli di anteprima che l’utente dimensiona a piacere.
- Viste master–detail — posta in arrivo e conversazione, tabella e ispettore del record, con il divisore dove lo vuole l’utente.
- Dashboard e console — lascia che un pannello di log o un terminale sottragga altezza alla vista principale senza una finestra modale.
Informazioni#
Il componente Resizable è basato su react-resizable-panels di bvaughn.
Installazione#
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
Installa le seguenti dipendenze:
pnpm add react-resizable-panelsnpm install react-resizable-panelsyarn add react-resizable-panelsbun add react-resizable-panels
Copia e incolla il seguente codice nel tuo progetto.
"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 }
Aggiorna i percorsi di importazione in base alla configurazione del tuo progetto.
Utilizzo#
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"<ResizablePanelGroup orientation="horizontal">
<ResizablePanel>One</ResizablePanel>
<ResizableHandle />
<ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>Composizione#
Usa la seguente composizione per costruire un ResizablePanelGroup:
ResizablePanelGroup
├── ResizablePanel
├── ResizableHandle
└── ResizablePanelEsempi#
Verticale#
Usa orientation="vertical" per un ridimensionamento verticale.
import {
ResizableHandle,
ResizablePanel,Maniglia#
Usa la prop withHandle su ResizableHandle per mostrare una maniglia visibile.
import {
ResizableHandle,
ResizablePanel,RTL#
Per abilitare il supporto RTL in Neobrutalism, consulta la guida alla configurazione RTL.
"use client"
import * as React from "react"Accessibilità#
La maniglia segue il pattern WAI-ARIA Window Splitter: react-resizable-panels rende ogni maniglia come role="separator" focalizzabile, con aria-valuenow / aria-valuemin / aria-valuemax e aria-controls che punta al pannello che ridimensiona, così gli screen reader annunciano la posizione della divisione man mano che cambia.
Interazioni da tastiera:
| Tasto | Azione |
|---|---|
Tab / Shift + Tab | Sposta il focus su una maniglia di ridimensionamento o via da essa |
ArrowLeft / ArrowRight | Ridimensiona un gruppo orizzontale di un passo |
ArrowUp / ArrowDown | Ridimensiona un gruppo verticale di un passo |
Home | Riduce il pannello prima della maniglia alla sua dimensione minima |
End | Espande il pannello prima della maniglia alla sua dimensione massima |
Enter | Alterna un pannello comprimibile tra chiuso ed espanso |
Riferimento API#
Consulta la documentazione react-resizable-panels.
Registro delle modifiche#
2025-02-02 react-resizable-panels v4#
Aggiornato a react-resizable-panels v4. Consulta le note di rilascio v4.0.0 per tutti i dettagli.
Se usi direttamente le primitive di react-resizable-panels, tieni presente le seguenti modifiche:
| 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 |
I componenti wrapper di Neobrutalism (ResizablePanelGroup, ResizablePanel,
ResizableHandle) rimangono invariati.