Skip to main content
PolyUI/docs

导航组件

标签页

在同一区域切换多组内容,支持键盘导航(方向键切换)和 ARIA tablist 语义。

安装

bash
pnpm dlx shadcn@latest add tabs -c packages/react

默认

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsDefault() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore">
        <TabsList>
          {TABS.map((tab) => (
            <TabsTrigger key={tab.value} value={tab.value}>
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

带图标

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsWithIcons() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" className="gap-4">
        <TabsList>
          {TABS.map(({ icon: Icon, name, value }) => (
            <TabsTrigger key={value} value={value} className="flex items-center gap-1 px-2.5 sm:px-3">
              <Icon />
              {name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

带徽章

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
import { Badge } from "@polyui/react/badge"
export function TabsWithBadge() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" className="gap-4">
        <TabsList>
          {TABS.map((tab) => (
            <TabsTrigger key={tab.value} value={tab.value} className="flex items-center gap-1 px-2.5 sm:px-3">
              {tab.name}
              <Badge className="h-5 min-w-5 px-1 tabular-nums">{tab.count}</Badge>
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

实色胶囊

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsSolidPills() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" className="gap-4">
        <TabsList className="bg-background">
          {TABS.map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="data-active:bg-primary dark:data-active:bg-primary data-active:text-primary-foreground dark:data-active:text-primary-foreground dark:data-active:border-transparent"
            >
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

描边胶囊

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsOutlinedPills() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" className="gap-4">
        <TabsList className="bg-background">
          {TABS.map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="data-active:border-border data-active:shadow-none"
            >
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

下划线

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsUnderline() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" className="gap-4">
        <TabsList className="bg-background rounded-none border-b p-0">
          {TABS.map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="bg-background data-active:border-primary dark:data-active:border-primary h-full rounded-none border-0 border-b-2 border-transparent data-active:shadow-none"
            >
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

直角

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsSharp() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" className="gap-4">
        <TabsList className="bg-background rounded-none border-b p-0">
          {TABS.map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="bg-background data-active:border-primary dark:data-active:border-primary h-full rounded-none border-b-2 border-transparent data-active:shadow-none"
            >
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

悬浮

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsLifted() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" className="gap-4">
        <TabsList className="bg-background justify-start rounded-none border-b p-0">
          {TABS.map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="bg-background border-b-border dark:data-active:bg-background data-active:border-border data-active:border-b-background h-full rounded-none rounded-t border border-transparent data-active:-mb-0.5 data-active:shadow-none dark:border-b-0 dark:data-active:-mb-0.5"
            >
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

自定义

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsCustom() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" className="gap-4">
        <TabsList className="bg-background gap-1">
          {TABS.map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="data-active:bg-primary dark:data-active:bg-primary data-active:text-primary-foreground dark:data-active:text-primary-foreground text-muted-foreground hover:text-foreground hover:bg-muted transition-colors duration-300 hover:border dark:data-active:border-transparent"
            >
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

自定义下划线

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsCustomUnderline() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" className="gap-4">
        <TabsList className="bg-background rounded-none border-b p-0">
          {TABS.map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="bg-background data-active:border-primary dark:data-active:border-primary data-active:text-foreground text-muted-foreground dark:text-muted-foreground hover:text-foreground dark:hover:text-foreground hover:border-muted-foreground/30 h-full rounded-none border-0 border-b-2 border-transparent data-active:shadow-none"
            >
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

垂直

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsVertical() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" orientation="vertical">
        <TabsList className="h-full">
          {TABS.map((tab) => (
            <TabsTrigger key={tab.value} value={tab.value} className="w-full">
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

垂直下划线

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsVerticalUnderline() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" orientation="vertical">
        <TabsList className="bg-background h-full rounded-none border-l p-0">
          {TABS.map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="bg-background data-active:border-primary dark:data-active:border-primary h-full w-full justify-start rounded-none border-0 border-l-2 border-transparent data-active:shadow-none"
            >
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

垂直柔和

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsVerticalSoft() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" orientation="vertical">
        <TabsList className="bg-background h-full">
          {TABS.map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="data-active:bg-primary/20 data-active:text-primary dark:data-active:text-primary dark:data-active:bg-primary/20 w-full data-active:shadow-none dark:data-active:border-transparent"
            >
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

垂直实色

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsVerticalSolid() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" orientation="vertical">
        <TabsList className="bg-background h-full">
          {TABS.map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="data-active:bg-primary dark:data-active:bg-primary data-active:text-primary-foreground dark:data-active:text-primary-foreground w-full dark:data-active:border-transparent"
            >
              {tab.name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

垂直带图标

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
export function TabsVerticalWithIcons() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" orientation="vertical">
        <TabsList className="h-full">
          {TABS.map(({ icon: Icon, name, value }) => (
            <TabsTrigger
              key={value}
              value={value}
              className="flex w-full items-center justify-start gap-1.5 px-2.5 sm:px-3"
            >
              <Icon />
              {name}
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

垂直带徽章

Discover fresh ideas, trending topics, and hidden gems curated just for you. Start exploring and let your curiosity lead the way!

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@polyui/react/tabs"
import { Badge } from "@polyui/react/badge"
export function TabsVerticalWithBadge() {
  return (
    <div className="w-full max-w-md">
      <Tabs defaultValue="explore" orientation="vertical">
        <TabsList className="h-full gap-1.5">
          {TABS.map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="flex w-full items-center justify-start gap-1.5 px-2.5 sm:px-3"
            >
              {tab.name}
              <Badge className="h-5 min-w-5 px-1 tabular-nums">{tab.count}</Badge>
            </TabsTrigger>
          ))}
        </TabsList>
        {TABS.map((tab) => (
          <TabsContent key={tab.value} value={tab.value}>
            <p className="text-muted-foreground text-sm">{tab.content}</p>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  )
}

属性

Tabs

属性类型默认值说明
defaultValuestring非受控默认选中项
valuestring受控选中项
onValueChange(value: string) => void切换回调
orientation"horizontal" | "vertical""horizontal"布局方向

TabsTrigger

属性类型默认值说明
value*string对应的 content 标识
disabledbooleanfalse禁用此标签

TabsContent

属性类型默认值说明
value*string对应的 trigger 标识
forceMountbooleanfalse始终挂载 DOM(用于 SSR 或动画)