Page Shell
WhereUIโครงแอปทั้งหน้าจอ: จอกว้างมี sidebar ซ้ายพื้นเข้ม (โทน sidebar) พร้อมแถบบน · มือถือมีแถบบนและรับ bottom-nav แทน เนื้อหาเลื่อนภายใน
ภาพรวมหน่วยงาน
ยอดสรุปเดือนพฤศจิกายน
ข้อมูล ณ 13 พ.ย. 2569
ติดตั้ง
Terminal
pnpm dlx shadcn@latest add @whereui/page-shellต้องผูก registry และติดตั้ง @whereui/theme นำหน้าเสมอเมื่อติดตั้งครั้งแรก
การใช้งาน
import { PageShell } from "@/components/ui/page-shell"<PageShell sidebar={<nav>…</nav>} header={<div>…</div>}> เนื้อหาหน้า</PageShell>ตัวอย่างเพิ่มเติม
ไม่มี sidebar — มือถือ/หน้าเดี่ยว
หน้าลงเวลาทำงาน
เนื้อหาเลื่อนขึ้นลงภายในกรอบ เหมาะกับหน้าเดี่ยวหรือจอมือถือที่ไม่ต้องมี sidebar
Props
| prop | type | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
| sidebar | React.ReactNode | — | เนื้อหา sidebar จอกว้าง (ตั้งแต่ md) ใช้โทนสี bg-sidebar — ซ่อนอัตโนมัติบนมือถือ |
| header | React.ReactNode | — | แถบบนติดขอบ เหนือเนื้อหา |
| bottomNav | React.ReactNode | — | โดยทั่วไปคือ <BottomNav> — แสดงเฉพาะมือถือก็ได้ โครงจะเว้นพื้นที่ล่างให้อัตโนมัติ |
| children | React.ReactNode | — | เนื้อหาหน้า อยู่ใน <main> เลื่อนภายใน |
| className | string | — | โครงสูงเท่าจอ (h-dvh) — เมื่อฝังในเอกสารจำกัดความสูงด้วย className="h-96" |
ข้อควรรู้
- แต่ละส่วนมี data-slot ของตัวเอง (page-shell-sidebar, page-shell-header, page-shell-main) สำหรับปรับแต่งจากภายนอก
- โทน sidebar มาจาก token ชุด sidebar ของธีม โหมดมืดปรับให้เอง
ซอร์สโค้ด
components/ui/page-shell.tsx
import * as React from "react"import { cn } from "cn"// โครงแอป: จอกว้างมี sidebar ซ้ายพื้นเข้ม + แถบบน · มือถือมีแถบบน + bottom-nav// ความสูงเต็มจอแล้วให้ main เลื่อนภายใน — จำกัดความสูงตอนฝังในเอกสารด้วย className เช่น "h-96"function PageShell({ className, sidebar, header, bottomNav, children, ...props}: React.ComponentProps<"div"> & { /** เนื้อหา sidebar จอกว้าง (ซ่อนอัตโนมัติบนมือถือ) */ sidebar?: React.ReactNode /** เนื้อหาแถบบน */ header?: React.ReactNode /** โดยทั่วไปคือ <BottomNav> สำหรับมือถือ */ bottomNav?: React.ReactNode}) { return ( <div data-slot="page-shell" className={cn("flex h-dvh w-full overflow-hidden bg-background", className)} {...props} > {sidebar ? ( <aside data-slot="page-shell-sidebar" className="hidden w-60 shrink-0 flex-col overflow-y-auto border-r border-sidebar-border bg-sidebar text-sidebar-foreground md:flex" > {sidebar} </aside> ) : null} <div data-slot="page-shell-body" className="flex min-w-0 flex-1 flex-col" > {header ? ( <header data-slot="page-shell-header" className="shrink-0 border-b bg-card" > {header} </header> ) : null} <main data-slot="page-shell-main" className={cn( "min-h-0 flex-1 overflow-y-auto px-4 py-6 sm:px-6", bottomNav ? "pb-28 md:pb-6" : null )} > {children} </main> </div> {bottomNav} </div> )}export { PageShell }