Naar inhoud

Herschalbaar

Versleepbare gesplitste vensters voor code-editors, bestandsboomstructuren en dashboardlay-outs — met die neobrutalistische stijl van randen en schaduwen.

import {
  ResizableHandle,
  ResizablePanel,

De resizable-component verdeelt een gebied in panelen waarvan de gebruiker de verhoudingen slepend aanpast — horizontaal of verticaal, nestbaar, met handles die ook met het toetsenbord te bedienen zijn. Beide varianten zijn een wrapper om react-resizable-panels van bvaughn, vormgegeven volgens het neobrutalistische recept: dikke randen, harde schaduwen en vette typografie.

Ideaal voor:

  • Code-editors en IDE-achtige lay-outs — bestandsboom, editor en previewpanelen die gebruikers naar eigen smaak op maat trekken.
  • Master-detailweergaven — inbox en gesprek, tabel en record-inspector, met de scheiding precies waar de gebruiker die hebben wil.
  • Dashboards en consoles — laat een logpaneel of terminal hoogte afsnoepen van de hoofdweergave, zonder modal.

Over

De component Resizable is gebouwd bovenop react-resizable-panels van bvaughn.

Installatie

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/resizable.json
npx shadcn@latest add https://neobrutalism.com/r/base/resizable.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/resizable.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/resizable.json

Installeer de volgende afhankelijkheden:

pnpm add react-resizable-panels
npm install react-resizable-panels
yarn add react-resizable-panels
bun add react-resizable-panels

Kopieer en plak de volgende code in je project.

components/ui/resizable.tsx
"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 }

Werk de importpaden bij zodat ze overeenkomen met je projectconfiguratie.

Gebruik

import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
<ResizablePanelGroup orientation="horizontal">
  <ResizablePanel>One</ResizablePanel>
  <ResizableHandle />
  <ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>

Compositie

Gebruik de volgende compositie om een ResizablePanelGroup op te bouwen:

ResizablePanelGroup
├── ResizablePanel
├── ResizableHandle
└── ResizablePanel

Voorbeelden

Verticaal

Gebruik orientation="vertical" om de grootte verticaal te wijzigen.

import {
  ResizableHandle,
  ResizablePanel,

Handvat

Gebruik de prop withHandle op ResizableHandle om een zichtbaar handvat te tonen.

import {
  ResizableHandle,
  ResizablePanel,

RTL

Om RTL-ondersteuning in Neobrutalism in te schakelen, zie de RTL-configuratiegids.

"use client"

import * as React from "react"

Toegankelijkheid

De handle volgt het WAI-ARIA Window Splitter-patroon: react-resizable-panels rendert elke handle als een focusbare role="separator" met aria-valuenow / aria-valuemin / aria-valuemax en een aria-controls die verwijst naar het paneel waarvan hij de grootte aanpast, zodat schermlezers de positie van de scheiding voorlezen terwijl die verandert.

Toetsenbordinteracties:

ToetsActie
Tab / Shift + TabVerplaatst de focus naar / weg van een resize-handle
ArrowLeft / ArrowRightPast de grootte van een horizontale groep met één stap aan
ArrowUp / ArrowDownPast de grootte van een verticale groep met één stap aan
HomeVerkleint het paneel vóór de handle tot zijn minimum
EndVergroot het paneel vóór de handle tot zijn maximum
EnterSchakelt een inklapbaar paneel tussen ingeklapt en uitgeklapt

API-referentie

Zie de documentatie van react-resizable-panels.

Changelog

2025-02-02 react-resizable-panels v4

Bijgewerkt naar react-resizable-panels v4. Zie de release notes voor v4.0.0 voor alle details.

Als je de primitives van react-resizable-panels rechtstreeks gebruikt, let dan op de volgende wijzigingen:

v3v4
PanelGroupGroup
PanelResizeHandleSeparator
direction proporientation prop
defaultSize={50}defaultSize="50%"
onLayoutonLayoutChange
ImperativePanelHandlePanelImperativeHandle
ref prop on PanelpanelRef prop
data-panel-group-directionaria-orientation