选项卡
查看源代码同一页面上相关面板之间切换的组件。
导入
import { Tabs, TabsList, TabsTab, TabsPanel } from "@resolid/react-ui";
Tabs
: 将选项卡和相应面板分组。TabsList
: 分组单个选项卡按钮。TabsTab
: 单个交互式选项卡按钮,可切换相应的面板。TabsPanel
: 当“对应”选项卡处于活动状态时显示的面板。
演示
选项卡默认只有必需的样式,你可以通过 Tabs
、TabsList
、TabsTab
和 TabsPanel
的 className
自定义。
import { SpriteIcon } from "~/components/sprite-icon";
import { Tabs, TabsList, TabsTab, TabsPanel } from "@resolid/react-ui";
export default function App() {
return (
<div className={"flex justify-center"}>
<Tabs defaultValue={"auto"} className={"border-bd-normal w-auto rounded-md border"}>
<TabsList className={"border-bd-normal gap-1 border-b p-1"}>
<TabsTab value={"auto"} className={"active:bg-bg-subtle rounded-md px-3"}>
Auto
</TabsTab>
<TabsTab value={"light"} className={"active:bg-bg-subtle rounded-md px-3"}>
Light
</TabsTab>
<TabsTab value={"dark"} className={"active:bg-bg-subtle 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>
</div>
);
}
举例
垂直
import { SpriteIcon } from "~/components/sprite-icon";
import { Tabs, TabsList, TabsTab, TabsPanel } from "@resolid/react-ui";
export default function App() {
return (
<div className={"flex justify-center"}>
<Tabs
className={"border-bd-normal w-auto rounded-md border"}
orientation={"vertical"}
defaultValue={"light"}
>
<TabsList className={"border-bd-normal border-e p-1"}>
<TabsTab value={"auto"} className={"active:bg-bg-subtle rounded-md px-3"}>
Auto
</TabsTab>
<TabsTab value={"light"} className={"active:bg-bg-subtle rounded-md px-3"}>
Light
</TabsTab>
<TabsTab value={"dark"} className={"active:bg-bg-subtle 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>
</div>
);
}
禁用
import { SpriteIcon } from "~/components/sprite-icon";
import { Tabs, TabsList, TabsTab, TabsPanel } from "@resolid/react-ui";
export default function App() {
return (
<div className={"flex justify-center"}>
<Tabs className={"border-bd-normal w-auto rounded-md border"} defaultValue={"auto"}>
<TabsList className={"border-bd-normal border-b p-1"}>
<TabsTab value={"auto"} className={"active:bg-bg-subtle rounded-md px-3"}>
Auto
</TabsTab>
<TabsTab
value={"light"}
disabled
className={"not-disabled:active:bg-bg-subtle rounded-md px-3"}
>
Light
</TabsTab>
<TabsTab value={"dark"} className={"active:bg-bg-subtle 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>
</div>
);
}
动态
这是如何动态添加和删除选项卡的示例。
import { useState } from "react";
import { Tabs, TabsList, TabsTab, TabsPanel, Button, CloseButton } from "@resolid/react-ui";
const items = [
{ id: "1", title: "Tab", content: "Tab Content" },
{ id: "2", title: "Tab", content: "Tab Content" },
{ id: "3", title: "Tab", content: "Tab Content" },
];
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 Body`,
},
]);
setSelected(uid);
};
const removeTab = (id) => {
if (tabs.length > 1) {
const newTabs = [...tabs].filter((tab) => tab.id !== id);
setTabs(newTabs);
if (id === selected) {
setSelected(newTabs[0].id);
}
}
};
return (
<Tabs
value={selected}
onChange={setSelected}
className={"border-bd-normal w-auto rounded-md border"}
>
<TabsList className={"border-bd-normal border-b p-1"}>
{tabs.map((tab) => {
return (
<TabsTab
render={(props) => <span {...props} />}
key={tab.id}
value={tab.id}
className={"active:bg-bg-subtle select-none 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"}
hasPadding={false}
className={"ms-1.5 px-1.5 py-0.5"}
color={"neutral"}
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
属性 | 类型 | 默认值 | 必须 | |
---|---|---|---|---|
属性defaultValue | 简介 默认值 | 类型string | 默认值- | 必须true |
属性value | 简介 受控值 | 类型string | 默认值- | 必须false |
属性onChange | 简介 onChange 回调 | 类型(value: string) => void | 默认值- | 必须false |
属性orientation | 简介 方向 | 类型"horizontal" | "vertical" | 默认值"horizontal" | 必须false |
TabsTab
属性 | 类型 | 默认值 | 必须 | |
---|---|---|---|---|
属性value | 简介 将内容与触发器关联起来的唯一值 | 类型string | 默认值- | 必须true |
属性disabled | 简介 是否禁用 | 类型boolean | 默认值false | 必须false |
TabsPanel
属性 | 类型 | 默认值 | 必须 | |
---|---|---|---|---|
属性value | 简介 将内容与触发器关联起来的唯一值 | 类型string | 默认值- | 必须true |