Segmented (default)

Underline

import { Tabs } from "@cloudflare/kumo";

export function TabsDefaultDemo() {
  return (
    <div className="flex flex-col items-start gap-6">
      <div>
        <p className="mb-2 text-sm text-kumo-subtle">Segmented (default)</p>
        <Tabs
          variant="segmented"
          tabs={[
            { value: "tab1", label: "Tab 1" },
            { value: "tab2", label: "Tab 2" },
            { value: "tab3", label: "Tab 3" },
          ]}
          selectedValue="tab1"
        />
      </div>
      <div>
        <p className="mb-2 text-sm text-kumo-subtle">Underline</p>
        <Tabs
          variant="underline"
          tabs={[
            { value: "tab1", label: "Tab 1" },
            { value: "tab2", label: "Tab 2" },
            { value: "tab3", label: "Tab 3" },
          ]}
          selectedValue="tab1"
        />
      </div>
    </div>
  );
}

安装

桶式导出

import { Tabs } from "@cloudflare/kumo";

细粒度导入

import { Tabs } from "@cloudflare/kumo/components/tabs";

用法

import { Tabs } from "@cloudflare/kumo";

export default function Example() {
  return (
    <Tabs
      tabs={[
        { value: "overview", label: "Overview" },
        { value: "settings", label: "Settings" },
      ]}
      selectedValue="overview"
    />
  );
}

示例

变体

分段式(默认)

胶囊形状的指示器在浅色背景上于选项卡之间滑动。

import { Tabs } from "@cloudflare/kumo";

export function TabsSegmentedDemo() {
  return (
    <Tabs
      variant="segmented"
      tabs={[
        { value: "tab1", label: "Tab 1" },
        { value: "tab2", label: "Tab 2" },
        { value: "tab3", label: "Tab 3" },
      ]}
      selectedValue="tab1"
    />
  );
}

下划线

底部边框配主色指示器。当前激活的选项卡 文字更粗,以示强调。

import { Tabs } from "@cloudflare/kumo";

export function TabsUnderlineDemo() {
  return (
    <Tabs
      variant="underline"
      tabs={[
        { value: "tab1", label: "Tab 1" },
        { value: "tab2", label: "Tab 2" },
        { value: "tab3", label: "Tab 3" },
      ]}
      selectedValue="tab1"
    />
  );
}

小尺寸

使用 size="sm" 得到紧凑的选项卡栏,与 Input size="sm" 高度一致(h-6.5 / 26px)。 适合放在工具栏和筛选行中。

Segmented sm

Underline sm

import { Tabs } from "@cloudflare/kumo";

export function TabsSmDemo() {
  return (
    <div className="flex flex-col items-start gap-6">
      <div>
        <p className="mb-2 text-sm text-kumo-subtle">Segmented sm</p>
        <Tabs
          variant="segmented"
          size="sm"
          tabs={[
            { value: "tab1", label: "Tab 1" },
            { value: "tab2", label: "Tab 2" },
            { value: "tab3", label: "Tab 3" },
          ]}
          selectedValue="tab1"
        />
      </div>
      <div>
        <p className="mb-2 text-sm text-kumo-subtle">Underline sm</p>
        <Tabs
          variant="underline"
          size="sm"
          tabs={[
            { value: "tab1", label: "Tab 1" },
            { value: "tab2", label: "Tab 2" },
            { value: "tab3", label: "Tab 3" },
          ]}
          selectedValue="tab1"
        />
      </div>
    </div>
  );
}

受控模式

使用 valueonValueChange 属性实现受控状态。

Active tab: tab1

import { useState } from "react";
import { Tabs } from "@cloudflare/kumo";

export function TabsControlledDemo() {
  const [activeTab, setActiveTab] = useState("tab1");

  return (
    <div className="space-y-4">
      <Tabs
        tabs={[
          { value: "tab1", label: "Tab 1" },
          { value: "tab2", label: "Tab 2" },
          { value: "tab3", label: "Tab 3" },
        ]}
        value={activeTab}
        onValueChange={setActiveTab}
      />
      <p className="text-sm text-kumo-subtle">
        Active tab: <code className="text-sm">{activeTab}</code>
      </p>
    </div>
  );
}

多选项卡

项目较多时,Tabs 会自动进行水平滚动。

import { Tabs } from "@cloudflare/kumo";

export function TabsManyDemo() {
  return (
    <div className="w-full max-w-md">
      <Tabs
        tabs={[
          { value: "overview", label: "Overview" },
          { value: "analytics", label: "Analytics" },
          { value: "reports", label: "Reports" },
          { value: "notifications", label: "Notifications" },
          { value: "settings", label: "Settings" },
          { value: "billing", label: "Billing" },
          { value: "security", label: "Security" },
          { value: "integrations", label: "Integrations" },
        ]}
        selectedValue="overview"
      />
    </div>
  );
}

水平溢出

当分段式选项卡溢出容器时,被裁剪的边缘会出现滚动按钮。可以使用 这些按钮、水平滚动或鼠标拖拽来 显示屏幕外的选项卡。

import { Tabs } from "@cloudflare/kumo";

export function TabsOverflowDemo() {
  return (
    <div className="w-full max-w-xs">
      <Tabs
        tabs={[
          { value: "overview", label: "Overview" },
          { value: "analytics", label: "Analytics" },
          { value: "reports", label: "Reports" },
          { value: "notifications", label: "Notifications" },
          { value: "settings", label: "Settings" },
          { value: "billing", label: "Billing" },
          { value: "security", label: "Security" },
          { value: "integrations", label: "Integrations" },
        ]}
        selectedValue="overview"
      />
    </div>
  );
}

动态选项卡数量

这个示例在溢出的选项卡集与类似生产环境的七选项卡集之间切换。当多余 选项卡消失后,剩余选项卡可以容纳时, 末尾的溢出控件应自动隐藏。

10 tabs
import { useState } from "react";
import { Tabs } from "@cloudflare/kumo";

export function TabsDynamicCountDemo() {
  const [showExtraTabs, setShowExtraTabs] = useState(true);
  const tabs = showExtraTabs
    ? [...productionLikeTabs, ...productionLikeExtraTabs]
    : productionLikeTabs;

  return (
    <div className="space-y-3">
      <div className="w-full max-w-[588px]">
        <Tabs tabs={tabs} selectedValue="settings" />
      </div>
      <div className="flex items-center gap-3 text-sm text-kumo-subtle">
        <button
          type="button"
          className="rounded-md border border-kumo-line bg-kumo-base px-2.5 py-1 text-kumo-default hover:bg-kumo-tint focus:ring-2 focus:ring-kumo-brand focus:outline-none"
          onClick={() => setShowExtraTabs((current) => !current)}
        >
          Toggle extra tabs
        </button>
        <span>{showExtraTabs ? "10 tabs" : "7 tabs"}</span>
      </div>
    </div>
  );
}

API 参考

PropTypeDefaultDescription
tabsTabsItem[]-Array of tab items to render.
valuestring-Controlled value. When set, component becomes controlled.
selectedValuestring-Default selected value for uncontrolled mode. Ignored when `value` is set.
activateOnFocusboolean-When `true`, tabs are activated immediately upon receiving focus via arrow keys. When `false` (default), tabs receive focus but require Enter/Space to activate.
classNamestring-Additional CSS classes for the root element.
listClassNamestring-Additional CSS classes for the tab list element.
indicatorClassNamestring-Additional CSS classes for the indicator element.
labelsTabsLabels-Labels for internationalization of aria-labels. All labels have English defaults.
variant"segmented" | "underline""segmented"Tab style. - `"segmented"` — Pill-shaped indicator on a filled track - `"underline"` — Underline indicator below tab text
size"base" | "sm""base"Tab size. - `"base"` — Default size (h-9, text-base) - `"sm"` — Compact size (h-6.5, text-xs) — matches Input size="sm"
onValueChange(value: string) => void-Callback when active tab changes

TabsItem

属性类型是否必需
valuestringYes
labelReactNodeYes
classNamestringNo
renderTabsTab.Props[“render”]No
nativeButtonbooleanNo