同一页面上相关面板之间切换的组件。

演示

import { SpriteIcon } from "~/components/sprite-icon";
import { Tabs, TabsList, TabsTab, TabsIndicator, TabsPanel } from "@resolid/react-ui";

export default function App() {
  return (
    <Tabs defaultValue={"auto"} className={"border-bd-normal w-auto rounded-md border"}>
      <TabsList className={"border-bd-normal gap-1 border-b p-1"}>
        <TabsIndicator className={"bg-bg-primary-emphasis w-(--wv) -bottom-px h-0.5"} />
        <TabsTab value={"auto"} className={"rounded-md px-3"}>
          Auto
        </TabsTab>
        <TabsTab value={"light"} className={"rounded-md px-3"}>
          Light
        </TabsTab>
        <TabsTab value={"dark"} className={"rounded-md px-3"}>
          Dark
        </TabsTab>
      </TabsList>
      <TabsPanel value={"auto"} className={"text-bg-muted flex items-center justify-center p-16"}>
        <SpriteIcon name={"auto"} size={"3rem"} />
      </TabsPanel>
      <TabsPanel value={"light"} className={"text-bg-muted flex items-center justify-center p-16"}>
        <SpriteIcon name={"sun"} size={"3rem"} />
      </TabsPanel>
      <TabsPanel value={"dark"} className={"text-bg-muted flex items-center justify-center p-16"}>
        <SpriteIcon name={"moon"} size={"3rem"} />
      </TabsPanel>
    </Tabs>
  );
}

使用

import { Tabs, TabsList, TabsTab, TabsIndicator, TabsPanel } from "@resolid/react-ui";
  • Tabs: 将选项卡和相应面板分组。
  • TabsList: 分组单个选项卡按钮。
  • TabsTab: 单个交互式选项卡按钮,可切换相应的面板。
  • TabsIndicator: 突出显示当前活动选项卡的指示器。
  • TabsPanel: 当“对应”选项卡处于活动状态时显示的面板。

选项卡默认只有必需的样式,你可以通过 TabsTabsListTabsTabTabsPanelclassName 自定义。

<Tabs>
  <TabsList>
    <TabsTab />
  </TabsList>
  <TabsPanel />
</Tabs>

特点

  • 遵循 WAI ARIA Tabs 设计模式。
  • 完整的键盘导航。
  • 支持水平/垂直方向。
  • 可以是受控的,也可以是不受控的。

举例

垂直

import { SpriteIcon } from "~/components/sprite-icon";
import { Tabs, TabsList, TabsIndicator, TabsTab, TabsPanel } from "@resolid/react-ui";

export default function App() {
  return (
    <Tabs
      className={"border-bd-normal w-auto rounded-md border"}
      orientation={"vertical"}
      defaultValue={"light"}
    >
      <TabsList className={"border-bd-normal border-e p-1"}>
        <TabsIndicator className={"bg-bg-subtle -z-1 w-(--wv) h-(--hv) rounded-md"} />
        <TabsTab value={"auto"} className={"rounded-md px-3"}>
          Auto
        </TabsTab>
        <TabsTab value={"light"} className={"rounded-md px-3"}>
          Light
        </TabsTab>
        <TabsTab value={"dark"} className={"rounded-md px-3"}>
          Dark
        </TabsTab>
      </TabsList>
      <TabsPanel value={"auto"} className={"text-bg-muted flex items-center justify-center p-16"}>
        <SpriteIcon name={"auto"} size={"3rem"} />
      </TabsPanel>
      <TabsPanel value={"light"} className={"text-bg-muted flex items-center justify-center p-16"}>
        <SpriteIcon name={"sun"} size={"3rem"} />
      </TabsPanel>
      <TabsPanel value={"dark"} className={"text-bg-muted flex items-center justify-center p-16"}>
        <SpriteIcon name={"moon"} size={"3rem"} />
      </TabsPanel>
    </Tabs>
  );
}

禁用

import { SpriteIcon } from "~/components/sprite-icon";
import { Tabs, TabsList, TabsTab, TabsIndicator, TabsPanel } from "@resolid/react-ui";

export default function App() {
  return (
    <Tabs className={"border-bd-normal w-auto rounded-md border"} defaultValue={"auto"}>
      <TabsList className={"border-bd-normal border-b p-1"}>
        <TabsIndicator className={"bg-bg-primary-emphasis w-(--wv) -bottom-px h-0.5"} />
        <TabsTab value={"auto"} className={"rounded-md px-3"}>
          Auto
        </TabsTab>
        <TabsTab value={"light"} disabled className={"rounded-md px-3"}>
          Light
        </TabsTab>
        <TabsTab value={"dark"} className={"rounded-md px-3"}>
          Dark
        </TabsTab>
      </TabsList>
      <TabsPanel value={"auto"} className={"text-bg-muted flex items-center justify-center p-16"}>
        <SpriteIcon name={"auto"} size={"3rem"} />
      </TabsPanel>
      <TabsPanel value={"light"} className={"text-bg-muted flex items-center justify-center p-16"}>
        <SpriteIcon name={"sun"} size={"3rem"} />
      </TabsPanel>
      <TabsPanel value={"dark"} className={"text-bg-muted flex items-center justify-center p-16"}>
        <SpriteIcon name={"moon"} size={"3rem"} />
      </TabsPanel>
    </Tabs>
  );
}

动态

这是如何动态添加和删除选项卡的示例。

Tab-1
import { useState } from "react";
import {
  Tabs,
  TabsList,
  TabsTab,
  TabsIndicator,
  TabsPanel,
  Button,
  CloseButton,
} from "@resolid/react-ui";

const items = [
  { id: "1", title: "Tab", content: "Tab-1" },
  { id: "2", title: "Tab", content: "Tab-2" },
  { id: "3", title: "Tab", content: "Tab-3" },
];

export default function App() {
  const [tabs, setTabs] = useState(items);
  const [selected, setSelected] = useState(items[0].id);

  const addTab = () => {
    const uid = Math.random().toString(36).substring(2, 15);

    setTabs([
      ...tabs,
      {
        id: uid,
        title: `Tab`,
        content: `Tab-${uid}`,
      },
    ]);

    setSelected(uid);
  };

  const removeTab = (id) => {
    if (tabs.length > 1) {
      const tabIndex = tabs.findIndex((tab) => tab.id === id);
      const newTabs = [...tabs.slice(0, tabIndex), ...tabs.slice(tabIndex + 1)];

      setTabs(newTabs);

      if (id === selected) {
        setSelected(newTabs[Math.max(tabIndex - 1, 0)].id);
      }
    }
  };

  return (
    <Tabs
      value={selected}
      onChange={setSelected}
      className={"border-bd-normal min-w-90 w-auto rounded-md border"}
    >
      <TabsList className={"border-bd-normal border-b p-1"}>
        <TabsIndicator className={"bg-bg-primary-emphasis w-(--wv) -bottom-px h-0.5"} />
        {tabs.map((tab) => {
          return (
            <TabsTab
              render={(props) => <div {...props} />}
              key={tab.id}
              value={tab.id}
              className={"inline-flex select-none items-center rounded-md pe-1 ps-3"}
            >
              {tab.title}
              <CloseButton
                size={"1em"}
                className={"ms-2"}
                onClick={(e) => {
                  e.stopPropagation();
                  removeTab(tab.id);
                }}
              />
            </TabsTab>
          );
        })}
        <Button
          variant={"ghost"}
          color={"neutral"}
          className={"ms-1.5 px-1.5 py-0.5"}
          noPadding
          onClick={addTab}
        >
          Add Tab
        </Button>
      </TabsList>
      {tabs.map((tab) => {
        return (
          <TabsPanel key={tab.id} value={tab.id} className={"p-4"}>
            {tab.content}
          </TabsPanel>
        );
      })}
    </Tabs>
  );
}

属性

Tabs

属性orientation简介

方向

类型"horizontal" | "vertical"默认值"horizontal"必须false
属性value简介

受控值

类型string默认值-必须false
属性defaultValue简介

默认值

类型string默认值-必须true
属性onChange简介

onChange 回调

类型(value: string) => void默认值-必须false

TabsTab

属性value简介

将内容与触发器关联起来的唯一值

类型string默认值-必须true
属性disabled简介

是否禁用

类型boolean默认值false必须false

TabsPanel

属性value简介

将内容与触发器关联起来的唯一值

类型string默认值-必须true

建议更改此页面