import { Tabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
const Demo = () => {
return (
<Tabs.Root defaultValue="members">
<Tabs.List>
<Tabs.Trigger value="members">
<LuUser />
Members
</Tabs.Trigger>
<Tabs.Trigger value="projects">
<LuFolder />
Projects
</Tabs.Trigger>
<Tabs.Trigger value="tasks">
<LuSquareCheck />
Settings
</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="members">Manage your team members</Tabs.Content>
<Tabs.Content value="projects">Manage your projects</Tabs.Content>
<Tabs.Content value="tasks">
Manage your tasks for freelancers
</Tabs.Content>
</Tabs.Root>
)
}
用法
import { Tabs } from "@chakra-ui/react"
<Tabs.Root>
<Tabs.List>
<Tabs.Trigger />
<Tabs.Indicator />
</Tabs.List>
<Tabs.Content />
</Tabs.Root>
示例
变体
使用 variant
属性更改选项卡的视觉样式。
import { For, SimpleGrid, Tabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
const Demo = () => {
return (
<SimpleGrid columns={2} gap="14" width="full">
<For each={["line", "subtle", "enclosed", "outline", "plain"]}>
{(variant) => (
<Tabs.Root key={variant} defaultValue="members" variant={variant}>
<Tabs.List>
<Tabs.Trigger value="members">
<LuUser />
Members
</Tabs.Trigger>
<Tabs.Trigger value="projects">
<LuFolder />
Projects
</Tabs.Trigger>
<Tabs.Trigger value="tasks">
<LuSquareCheck />
Settings
</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="members">
Manage your team members
</Tabs.Content>
<Tabs.Content value="projects">Manage your projects</Tabs.Content>
<Tabs.Content value="tasks">
Manage your tasks for freelancers
</Tabs.Content>
</Tabs.Root>
)}
</For>
</SimpleGrid>
)
}
懒加载
使用 lazyMount
和/或 unmountOnExit
属性,仅在选项卡处于活动状态时渲染其内容。这对于性能优化很有用。
"use client"
import { Tabs } from "@chakra-ui/react"
import { useEffect, useState } from "react"
const Demo = () => {
return (
<Tabs.Root lazyMount unmountOnExit defaultValue="tab-1">
<Tabs.List>
<Tabs.Trigger value="tab-1">Tab 1</Tabs.Trigger>
<Tabs.Trigger value="tab-2">Tab 2</Tabs.Trigger>
<Tabs.Trigger value="tab-3">Tab 3</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="tab-1">
Tab 1: Content <TickValue />
</Tabs.Content>
<Tabs.Content value="tab-2">
Tab 2: Content <TickValue />
</Tabs.Content>
<Tabs.Content value="tab-3">
Tab 3: Content <TickValue />
</Tabs.Content>
</Tabs.Root>
)
}
const TickValue = () => {
const [value, setValue] = useState(0)
useEffect(() => {
const intervalId = window.setInterval(() => {
setValue((v) => v + 1)
}, 1000)
return () => {
window.clearInterval(intervalId)
}
}, [])
return (
<span style={{ fontWeight: "bold", color: "tomato", padding: 4 }}>
{value}
</span>
)
}
指示器
渲染 Tabs.Indicator
组件以显示活动选项卡的视觉指示器。
import { Tabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
const Demo = () => {
return (
<Tabs.Root defaultValue="members" variant="plain">
<Tabs.List bg="bg.muted" rounded="l3" p="1">
<Tabs.Trigger value="members">
<LuUser />
Members
</Tabs.Trigger>
<Tabs.Trigger value="projects">
<LuFolder />
Projects
</Tabs.Trigger>
<Tabs.Trigger value="tasks">
<LuSquareCheck />
Settings
</Tabs.Trigger>
<Tabs.Indicator rounded="l2" />
</Tabs.List>
<Tabs.Content value="members">Manage your team members</Tabs.Content>
<Tabs.Content value="projects">Manage your projects</Tabs.Content>
<Tabs.Content value="tasks">
Manage your tasks for freelancers
</Tabs.Content>
</Tabs.Root>
)
}
链接
将 asChild
传递给 Tabs.Trigger
组件,将链接渲染为选项卡。点击选项卡时,将导航到该链接。
import { Link, Tabs } from "@chakra-ui/react"
const Demo = () => {
return (
<Tabs.Root defaultValue="members">
<Tabs.List>
<Tabs.Trigger value="members" asChild>
<Link unstyled href="#members">
Members
</Link>
</Tabs.Trigger>
<Tabs.Trigger value="projects" asChild>
<Link unstyled href="#projects">
Projects
</Link>
</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="members">Manage your team members</Tabs.Content>
<Tabs.Content value="projects">Manage your projects</Tabs.Content>
</Tabs.Root>
)
}
当使用自定义路由链接时,您需要在 Tabs.Root
组件上设置 navigate
属性。
"use client"
import { Tabs } from "@chakra-ui/react"
import { useNavigate } from "react-router-dom"
const Demo = () => {
const navigate = useNavigate()
return (
<Tabs.Root navigate={({ value, node }) => navigate(`/${value}`)}>
{/* ... */}
</Tabs.Root>
)
}
自适应
使用 fitted
属性使选项卡适应容器的宽度。
import { Tabs } from "@chakra-ui/react"
const Demo = () => {
return (
<Tabs.Root variant="enclosed" maxW="md" fitted defaultValue={"tab-1"}>
<Tabs.List>
<Tabs.Trigger value="tab-1">Tab 1</Tabs.Trigger>
<Tabs.Trigger value="tab-2">Tab 2</Tabs.Trigger>
<Tabs.Trigger value="tab-3">Tab 3</Tabs.Trigger>
</Tabs.List>
</Tabs.Root>
)
}
受控
使用 value
和 onValueChange
属性来控制活动选项卡。
"use client"
import { Tabs } from "@chakra-ui/react"
import { useState } from "react"
const Demo = () => {
const [value, setValue] = useState<string | null>("first")
return (
<Tabs.Root value={value} onValueChange={(e) => setValue(e.value)}>
<Tabs.List>
<Tabs.Trigger value="first">First tab</Tabs.Trigger>
<Tabs.Trigger value="second">Second tab</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="first">First panel</Tabs.Content>
<Tabs.Content value="second">Second panel</Tabs.Content>
</Tabs.Root>
)
}
存储
控制选项卡的另一种方法是使用 RootProvider
组件和 useTabs
存储钩子。
通过这种方式,您可以从选项卡外部访问选项卡的状态和方法。
已选择成员
"use client"
import { Code, Stack, Tabs, useTabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
const Demo = () => {
const tabs = useTabs({
defaultValue: "members",
})
return (
<Stack align="flex-start">
<Code>selected: {tabs.value}</Code>
<Tabs.RootProvider value={tabs}>
<Tabs.List>
<Tabs.Trigger value="members">
<LuUser />
Members
</Tabs.Trigger>
<Tabs.Trigger value="projects">
<LuFolder />
Projects
</Tabs.Trigger>
<Tabs.Trigger value="tasks">
<LuSquareCheck />
Tasks
</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="members">Manage your team members</Tabs.Content>
<Tabs.Content value="projects">Manage your projects</Tabs.Content>
<Tabs.Content value="tasks">
Manage your tasks for freelancers
</Tabs.Content>
</Tabs.RootProvider>
</Stack>
)
}
禁用选项卡
在 Tabs.Trigger
组件上设置 disabled
属性以禁用选项卡。
import { Tabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
const Demo = () => {
return (
<Tabs.Root defaultValue="members">
<Tabs.List>
<Tabs.Trigger value="members">
<LuUser />
Members
</Tabs.Trigger>
<Tabs.Trigger value="projects" disabled>
<LuFolder />
Projects
</Tabs.Trigger>
<Tabs.Trigger value="tasks">
<LuSquareCheck />
Settings
</Tabs.Trigger>
</Tabs.List>
{/* content */}
</Tabs.Root>
)
}
手动激活
默认情况下,当按下方向键时,选项卡会被选中。通过将 activationBehavior
属性设置为 manual
来禁用此行为。
在此模式下,选项卡只有在被点击或按下回车键时才会被选中。
import { Tabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
const Demo = () => {
return (
<Tabs.Root defaultValue="members" activationMode="manual">
<Tabs.List>
<Tabs.Trigger value="members">
<LuUser />
Members
</Tabs.Trigger>
<Tabs.Trigger value="projects" disabled>
<LuFolder />
Projects
</Tabs.Trigger>
<Tabs.Trigger value="tasks">
<LuSquareCheck />
Settings
</Tabs.Trigger>
</Tabs.List>
{/* content */}
</Tabs.Root>
)
}
动态
这是一个如何动态添加和移除选项卡的示例。
选项卡内容 1
Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit.
选项卡内容 2
Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit.
选项卡内容 3
Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit.
选项卡内容 4
Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. Id cupidatat aute id ut excepteur exercitation magna pariatur. Mollit irure irure reprehenderit pariatur eiusmod proident Lorem deserunt duis cillum mollit.
"use client"
import { Button, CloseButton, Heading, Tabs, Text } from "@chakra-ui/react"
import { useState } from "react"
import { LuPlus } from "react-icons/lu"
interface Item {
id: string
title: string
content: React.ReactNode
}
const items: Item[] = [
{ id: "1", title: "Tab", content: "Tab Content" },
{ id: "2", title: "Tab", content: "Tab Content" },
{ id: "3", title: "Tab", content: "Tab Content" },
{ id: "4", title: "Tab", content: "Tab Content" },
]
const uuid = () => {
return Math.random().toString(36).substring(2, 15)
}
const Demo = () => {
const [tabs, setTabs] = useState<Item[]>(items)
const [selectedTab, setSelectedTab] = useState<string | null>(items[0].id)
const addTab = () => {
const newTabs = [...tabs]
const uid = uuid()
newTabs.push({
id: uid,
title: `Tab`,
content: `Tab Body`,
})
setTabs(newTabs)
setSelectedTab(newTabs[newTabs.length - 1].id)
}
const removeTab = (id: string) => {
if (tabs.length > 1) {
const newTabs = [...tabs].filter((tab) => tab.id !== id)
setTabs(newTabs)
}
}
return (
<Tabs.Root
value={selectedTab}
variant="outline"
size="sm"
onValueChange={(e) => setSelectedTab(e.value)}
>
<Tabs.List flex="1 1 auto">
{tabs.map((item) => (
<Tabs.Trigger value={item.id} key={item.id}>
{item.title}{" "}
<CloseButton
as="span"
role="button"
size="2xs"
me="-2"
onClick={(e) => {
e.stopPropagation()
removeTab(item.id)
}}
/>
</Tabs.Trigger>
))}
<Button
alignSelf="center"
ms="2"
size="2xs"
variant="ghost"
onClick={addTab}
>
<LuPlus /> Add Tab
</Button>
</Tabs.List>
<Tabs.ContentGroup>
{tabs.map((item) => (
<Tabs.Content value={item.id} key={item.id}>
<Heading size="xl" my="6">
{item.content} {item.id}
</Heading>
<Text>
Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam
Lorem est occaecat do magna nisi mollit ipsum sit adipisicing
fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. Id
cupidatat aute id ut excepteur exercitation magna pariatur. Mollit
irure irure reprehenderit pariatur eiusmod proident Lorem deserunt
duis cillum mollit.
</Text>
</Tabs.Content>
))}
</Tabs.ContentGroup>
</Tabs.Root>
)
}
动画
使用 _open
和 _close
条件属性来为选项卡添加动画。
import { Box, Flex, Tabs } from "@chakra-ui/react"
const items = [
{
title: "1",
content: "Dolore ex esse laboris elit magna esse sunt",
},
{
title: "2",
content:
"Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex.",
},
]
const Demo = () => {
return (
<Flex minH="dvh">
<Tabs.Root defaultValue="1" width="full">
<Tabs.List>
{items.map((item, index) => (
<Tabs.Trigger key={index} value={item.title}>
Tab {item.title}
</Tabs.Trigger>
))}
</Tabs.List>
<Box pos="relative" minH="200px" width="full">
{items.map((item, index) => (
<Tabs.Content
key={index}
value={item.title}
position="absolute"
inset="0"
_open={{
animationName: "fade-in, scale-in",
animationDuration: "300ms",
}}
_closed={{
animationName: "fade-out, scale-out",
animationDuration: "120ms",
}}
>
{item.content}
</Tabs.Content>
))}
</Box>
</Tabs.Root>
</Flex>
)
}
属性
根
属性 | 默认值 | 类型 |
---|---|---|
activationMode | '\'automatic\'' | 'manual' | 'automatic' 选项卡的激活模式。可以是 `manual` 或 `automatic` - `manual`:点击或按下 `enter` 键时激活选项卡。 - `automatic`:获得焦点时激活选项卡。 |
lazyMount | false | 布尔值 是否启用懒加载 |
loopFocus | true | 布尔值 键盘导航是否会在最后一个选项卡和第一个选项卡之间循环。 |
orientation | '\'horizontal\'' | 'horizontal' | 'vertical' 选项卡的排列方向。可以是 `horizontal` 或 `vertical` - `horizontal`:仅支持左右方向键导航。 - `vertical`:仅支持上下方向键导航。 |
unmountOnExit | false | 布尔值 退出时是否卸载。 |
colorPalette | 'gray' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink' 组件的调色板 |
size | 'md' | 'sm' | 'md' | 'lg' 组件的大小 |
variant | 'line' | 'line' | 'subtle' | 'enclosed' | 'outline' | 'plain' 组件的变体 |
asChild | ||
composite | 布尔值 选项卡是否是组合的 | |
defaultValue | 字符串 选项卡首次渲染时的初始值。在您不需要控制选项卡状态时使用。 | |
deselectable | 布尔值 点击时是否可以取消选中活动选项卡。 | |
id | 字符串 机器的唯一标识符。 | |
ids | Partial<{ root: string trigger: string list: string content: string indicator: string }> 选项卡中元素的 ID。对于组合很有用。 | |
navigate | (details: NavigateDetails) => void 点击时导航到选中选项卡的函数。如果选项卡触发器是锚点元素,则很有用。 | |
onFocusChange | (details: FocusChangeDetails) => void 当焦点选项卡改变时调用的回调函数 | |
onValueChange | (details: ValueChangeDetails) => void 当选中/活动选项卡改变时调用的回调函数 | |
translations | IntlTranslations 指定用于标识可访问性元素及其状态的本地化字符串 | |
value | 字符串 选中的选项卡 ID | |
fitted | 'true' | 'false' 组件的自适应模式 | |
justify | 'start' | 'center' | 'end' 组件的对齐方式 |
触发器
属性 | 默认值 | 类型 |
---|---|---|
value * | 字符串 选项卡的值 | |
asChild | ||
disabled | 布尔值 选项卡是否被禁用 |
内容
属性 | 默认值 | 类型 |
---|---|---|
value * | 字符串 选项卡的值 | |
asChild |