Có thể đổi kích thước
Các khung chia đôi có thể kéo thả dành cho trình soạn thảo mã nguồn, cây thư mục và bố cục bảng điều khiển — với phong cách viền và bóng theo trường phái tân thô mộc.
import {
ResizableHandle,
ResizablePanel,Thành phần resizable chia một vùng thành các panel mà người dùng có thể kéo để thay đổi tỷ lệ — theo chiều ngang hoặc dọc, lồng nhau được, với tay kéo điều khiển được bằng bàn phím. Cả hai biến thể đều bọc thư viện react-resizable-panels của bvaughn, tạo kiểu theo công thức neobrutalist: viền dày, bóng đổ đậm và kiểu chữ đậm.
Nên dùng khi:
- Trình soạn mã và bố cục kiểu IDE — các khung cây tệp, trình soạn thảo và xem trước để người dùng tự chỉnh kích thước theo ý.
- Giao diện master–detail — hộp thư và luồng hội thoại, bảng dữ liệu và khung xem chi tiết bản ghi, với vạch chia đặt đúng chỗ người dùng muốn.
- Bảng điều khiển và console — cho phép khung log hoặc terminal lấy bớt chiều cao của khung chính mà không cần modal.
Giới thiệu#
Component Resizable được xây dựng dựa trên react-resizable-panels của bvaughn.
Cài đặt#
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
Cài đặt các phụ thuộc sau:
pnpm add react-resizable-panelsnpm install react-resizable-panelsyarn add react-resizable-panelsbun add react-resizable-panels
Sao chép và dán đoạn mã sau vào dự án của bạn.
"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 }
Cập nhật các đường dẫn import cho phù hợp với thiết lập dự án của bạn.
Cách dùng#
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"<ResizablePanelGroup orientation="horizontal">
<ResizablePanel>One</ResizablePanel>
<ResizableHandle />
<ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>Kết hợp#
Dùng cách kết hợp sau để xây dựng một ResizablePanelGroup:
ResizablePanelGroup
├── ResizablePanel
├── ResizableHandle
└── ResizablePanelVí dụ#
Dọc#
Dùng orientation="vertical" để thay đổi kích thước theo chiều dọc.
import {
ResizableHandle,
ResizablePanel,Tay cầm#
Dùng prop withHandle trên ResizableHandle để hiển thị một tay cầm nhìn thấy được.
import {
ResizableHandle,
ResizablePanel,RTL#
Để bật hỗ trợ RTL trong Neobrutalism, hãy xem hướng dẫn cấu hình RTL.
"use client"
import * as React from "react"Khả năng truy cập#
Tay kéo tuân theo mẫu Window Splitter của WAI-ARIA: react-resizable-panels render mỗi tay kéo thành một phần tử role="separator" có thể focus, kèm aria-valuenow / aria-valuemin / aria-valuemax và aria-controls trỏ đến panel mà nó thay đổi kích thước, nhờ đó trình đọc màn hình đọc lên vị trí vạch chia mỗi khi thay đổi.
Tương tác bàn phím:
| Phím | Hành động |
|---|---|
Tab / Shift + Tab | Di chuyển focus vào / ra khỏi tay kéo |
ArrowLeft / ArrowRight | Thay đổi kích thước nhóm ngang theo từng bước |
ArrowUp / ArrowDown | Thay đổi kích thước nhóm dọc theo từng bước |
Home | Thu panel đứng trước tay kéo về kích thước tối thiểu |
End | Mở rộng panel đứng trước tay kéo đến kích thước tối đa |
Enter | Chuyển panel có thể thu gọn giữa trạng thái thu gọn và mở rộng |
Tham chiếu API#
Xem tài liệu react-resizable-panels.
Nhật ký thay đổi#
2025-02-02 react-resizable-panels v4#
Đã cập nhật lên react-resizable-panels v4. Xem ghi chú phát hành v4.0.0 để biết đầy đủ chi tiết.
Nếu bạn dùng trực tiếp các primitive của react-resizable-panels, hãy lưu ý các thay đổi sau:
| 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 |
Các component wrapper của Neobrutalism (ResizablePanelGroup, ResizablePanel,
ResizableHandle) vẫn không thay đổi.