Page Header
WhereUIส่วนหัวของหน้า: breadcrumb ชื่อหน้า คำอธิบาย ปุ่มการกระทำฝั่งขวา และปุ่มย้อนกลับนำหน้าชื่อ เมื่อจำเป็น
โปรไฟล์พนักงาน
ข้อมูลส่วนตัว ตำแหน่ง และประวัติการทำงาน
ติดตั้ง
Terminal
pnpm dlx shadcn@latest add @whereui/page-headerต้องผูก registry และติดตั้ง @whereui/theme นำหน้าเสมอเมื่อติดตั้งครั้งแรก
การใช้งาน
import { PageHeader } from "@/components/ui/page-header"<PageHeader title="โปรไฟล์พนักงาน" description="ข้อมูลส่วนตัวและประวัติการทำงาน" breadcrumbs={[{ label: "หน้าแรก", href: "/" }, { label: "พนักงาน" }]}/>ตัวอย่างเพิ่มเติม
มีปุ่มย้อนกลับ
คำขอลากิจ WH-2569-0142
ส่งเมื่อ 11 พ.ย. 2569 09:15 · รอหัวหน้างานพิจารณา
Props
| prop | type | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
| title | React.ReactNode | — | ชื่อหน้า เป็น <h1> |
| description | React.ReactNode | — | คำอธิบายใต้ชื่อหน้า |
| breadcrumbs | { label: string; href?: string }[] | — | รายการ breadcrumb — รายการสุดท้ายเป็นหน้าปัจจุบัน รายการที่ไม่มี href แสดงเป็นข้อความกดไม่ได้ |
| actions | React.ReactNode | — | ปุ่มการกระทำฝั่งขวา เช่น <Button> |
| onBack | () => void | — | ถ้าส่งมาจะมีปุ่มลูกศรย้อนกลับนำหน้าชื่อหน้า |
ข้อควรรู้
- ปุ่มการกระทับ (actions) ตกบรรทัดใหม่เองบนจอแคบ ไม่ล้นที่ 375px
ซอร์สโค้ด
components/ui/page-header.tsx
import * as React from "react"import { ArrowLeftIcon } from "lucide-react"import { cn } from "cn"import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator,} from "@/components/ui/breadcrumb"import { Button } from "@/components/ui/button"export type PageHeaderBreadcrumb = { label: string /** ไม่ใส่ = ลิงก์เปล่า (จุดที่กดไม่ได้) รายการสุดท้ายจะเป็นหน้าปัจจุบันเสมอ */ href?: string}function PageHeader({ className, title, description, breadcrumbs, actions, onBack, ...props}: React.ComponentProps<"div"> & { title: React.ReactNode description?: React.ReactNode breadcrumbs?: PageHeaderBreadcrumb[] /** ปุ่มการกระทำฝั่งขวา เช่น <Button> */ actions?: React.ReactNode /** ถ้าส่งมาจะแสดงปุ่มย้อนกลับนำหน้าชื่อหน้า */ onBack?: () => void}) { return ( <div data-slot="page-header" className={cn("flex w-full flex-col gap-3", className)} {...props} > {breadcrumbs?.length ? ( <Breadcrumb> <BreadcrumbList> {breadcrumbs.map((crumb, i) => { const isLast = i === breadcrumbs.length - 1 return ( <React.Fragment key={i}> {i > 0 ? <BreadcrumbSeparator /> : null} <BreadcrumbItem> {isLast ? ( <BreadcrumbPage>{crumb.label}</BreadcrumbPage> ) : crumb.href ? ( <BreadcrumbLink href={crumb.href}> {crumb.label} </BreadcrumbLink> ) : ( <span className="text-muted-foreground"> {crumb.label} </span> )} </BreadcrumbItem> </React.Fragment> ) })} </BreadcrumbList> </Breadcrumb> ) : null} <div className="flex flex-wrap items-start justify-between gap-x-4 gap-y-3"> <div className="flex min-w-0 items-start gap-2"> {onBack ? ( <Button variant="ghost" size="icon-sm" aria-label="ย้อนกลับ" className="-ml-2 mt-0.5 shrink-0" onClick={onBack} > <ArrowLeftIcon /> </Button> ) : null} <div className="min-w-0"> <h1 className="font-heading text-xl leading-tight font-semibold tracking-tight text-balance"> {title} </h1> {description ? ( <p className="mt-1 text-sm text-muted-foreground text-balance"> {description} </p> ) : null} </div> </div> {actions ? ( <div data-slot="page-header-actions" className="flex shrink-0 flex-wrap items-center gap-2" > {actions} </div> ) : null} </div> </div> )}export { PageHeader }