ข้ามไปเนื้อหา
WhereUI

ค้นหาในเอกสาร

ค้นหาชื่อ component หรือหน้าเอกสาร

Bottom Nav

WhereUI

แถบนำทางล่างสำหรับมือถือ 3–5 ปุ่ม ไอคอนพร้อมป้ายกำกับ รองรับสถานะ active ตัวเลขแจ้งเตือน และเว้นระยะ safe area ด้านล่างจอ

ติดตั้ง

Terminal
pnpm dlx shadcn@latest add @whereui/bottom-nav

ต้องผูก registry และติดตั้ง @whereui/theme นำหน้าเสมอเมื่อติดตั้งครั้งแรก

การใช้งาน

import { BottomNav, BottomNavItem } from "@/components/ui/bottom-nav"import { HomeIcon } from "lucide-react"<BottomNav>  <BottomNavItem href="/" label="หน้าแรก" active>    <HomeIcon />  </BottomNavItem></BottomNav>

ตัวอย่างเพิ่มเติม

สามปุ่ม ไม่มี badge

Props

proptypeค่าเริ่มต้นคำอธิบาย
classNamestring—BottomNav ติดล่างจอด้วย fixed — ส่ง className="relative rounded-xl border" เพื่อวางในลำดับเอกสารแทน
hrefstring—ปลายทางของปุ่ม (BottomNavItem เป็น <a>)
activebooleanfalseหน้าปัจจุบัน — เป็นสี primary และใส่ aria-current="page"
badgenumber—ตัวเลขแจ้งเตือนที่มุมไอคอน เกิน 99 แสดง 99+
labelstring—ข้อความใต้ไอคอน
childrenReact.ReactNode—ไอคอนของปุ่ม เช่น <HomeIcon />

ข้อควรรู้

  • แถบเว้นความสูง env(safe-area-inset-bottom) ให้เนื้อหาหน้าเว้นพื้นที่ด้านล่างด้วย เช่น pb-24 เพื่อไม่ให้ตกใต้แถบ
  • ความสูงปุ่มขั้นต่ำ 56px เหมาะกับการกดด้วยนิ้วบนจอสัมผัส
  • ใช้คู่กับ PageShell ผ่านสล็อต bottomNav เพื่อโครงแอปที่สมบูรณ์

ซอร์สโค้ด

components/ui/bottom-nav.tsx
import * as React from "react"import { cn } from "cn"// แถบนำทางล่างสำหรับมือถือ — ใช้คู่กับ PageShell (สล็อต bottomNav) หรือวางเดี่ยวfunction BottomNav({ className, ...props }: React.ComponentProps<"nav">) {  return (    <nav      data-slot="bottom-nav"      aria-label="การนำทางหลัก"      className={cn(        "fixed inset-x-0 bottom-0 z-40 flex items-stretch justify-around border-t bg-card/95 pb-[env(safe-area-inset-bottom)] text-muted-foreground backdrop-blur",        className      )}      {...props}    />  )}function BottomNavItem({  className,  active = false,  badge,  label,  children,  ...props}: React.ComponentProps<"a"> & {  /** ทำเครื่องหมายว่าเป็นหน้าปัจจุบัน */  active?: boolean  /** ตัวเลขแจ้งเตือน (เกิน 99 แสดง 99+) */  badge?: number  /** ข้อความใต้ไอคอน */  label: string}) {  return (    <a      data-slot="bottom-nav-item"      data-active={active}      aria-current={active ? "page" : undefined}      className={cn(        "flex min-h-14 min-w-14 flex-1 flex-col items-center justify-center gap-0.5 rounded-lg px-1 pb-1 pt-1.5 text-[0.7rem] font-medium transition-colors outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/50 data-[active=true]:text-primary",        className      )}      {...props}    >      <span        data-slot="bottom-nav-icon"        className="relative [&_svg]:size-5"      >        {children}        {badge ? (          <span            data-slot="bottom-nav-badge"            className="absolute -top-1.5 -right-2 grid h-4 min-w-4 place-items-center rounded-4xl bg-destructive px-0.5 text-[10px] leading-none font-semibold text-primary-foreground tabular-nums"          >            {badge > 99 ? "99+" : badge}          </span>        ) : null}      </span>      {label}    </a>  )}export { BottomNav, BottomNavItem }