For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms-full.txt, and this page is available as Markdown at https://ifhover.github.io/leaf-ui/v/0.6.0/components/tabs.md.
  • 简体中文
  • Tabs 标签页

    在同一区域切换不同内容。

    切换时正文和内容区域高度立即更新,不使用过渡动画;标签栏的选中指示线保留移动效果。

    卡片样式的标签栏默认随标签内容调整宽度,空间不足时在栏内滚动。size 控制整个标签栏的尺寸,正文区域使用可用宽度。

    基础用法

    线形标签
    查看项目活动、成员和最近更新。
    卡片标签
    查看项目活动、成员和最近更新。
    纵向标签
    查看项目活动、成员和最近更新。
    basic.tsx
    import type { TabItem } from '@ifhover/leaf-ui';
    
    import { Input, Space, Tabs } from '@ifhover/leaf-ui';
    
    import { ChartNoAxesColumn, Settings } from 'lucide-react';
    
    const items: readonly TabItem[] = [
      {
        key: 'overview',
        label: '概览',
        icon: <ChartNoAxesColumn />,
        children: '查看项目活动、成员和最近更新。',
      },
      {
        key: 'settings',
        label: '设置',
        icon: <Settings />,
        children: <Input aria-label="项目名称" placeholder="输入内容后切换,内容会保留" />,
      },
      { key: 'history', label: '历史', disabled: true, children: null },
    ];
    
    export function TabsBasic() {
      return (
        <Space direction="vertical" align="stretch">
          <Space direction="vertical" align="stretch" size="sm">
            <span>线形标签</span>
            <Tabs aria-label="项目信息" items={items} />
          </Space>
          <Space direction="vertical" align="stretch" size="sm">
            <span>卡片标签</span>
            <Tabs aria-label="卡片标签" items={items} type="card" />
          </Space>
          <Space direction="vertical" align="stretch" size="sm">
            <span>纵向标签</span>
            <Tabs aria-label="纵向标签" items={items} placement="left" />
          </Space>
        </Space>
      );
    }
    

    不同尺寸

    线形与卡片标签分别展示小、默认和大尺寸。

    线形标签
    小尺寸
    查看项目的最近更新。
    默认尺寸
    查看项目的最近更新。
    大尺寸
    查看项目的最近更新。
    卡片标签
    小尺寸
    查看项目的最近更新。
    默认尺寸
    查看项目的最近更新。
    大尺寸
    查看项目的最近更新。
    sizes.tsx
    import { Grid, Space, Tabs, Text } from '@ifhover/leaf-ui';
    
    const items = [
      { key: 'overview', label: '概览', children: '查看项目的最近更新。' },
      { key: 'members', label: '成员', children: '管理项目成员和访问权限。' },
    ];
    
    const labels = { sm: '小尺寸', md: '默认尺寸', lg: '大尺寸' };
    
    const variants = [
      { type: 'line', label: '线形标签' },
      { type: 'card', label: '卡片标签' },
    ] as const;
    
    export function TabsSizes() {
      return (
        <Grid columns={{ xs: 1, sm: 2 }} gap={24}>
          {variants.map(({ type, label }) => (
            <Space key={type} direction="vertical" align="stretch" size="lg">
              <Text strong>{label}</Text>
              {(['sm', 'md', 'lg'] as const).map((size) => (
                <Space key={size} direction="vertical" align="stretch" size="sm">
                  <span>{labels[size]}</span>
                  <Tabs
                    aria-label={`${label} · ${labels[size]}`}
                    items={items}
                    type={type}
                    size={size}
                  />
                </Space>
              ))}
            </Space>
          ))}
        </Grid>
      );
    }
    

    可关闭标签页

    点击加号新增标签页。全部关闭后组件隐藏,可使用示例中的新增按钮重新打开。

    项目一的内容
    closable.tsx
    import { Button, Space, type TabItem, Tabs } from '@ifhover/leaf-ui';
    
    import { useRef, useState } from 'react';
    
    export function TabsClosable() {
      const sequence = useRef(2);
      const [items, setItems] = useState<TabItem[]>([
        { key: '1', label: '项目一', children: '项目一的内容', closable: true },
        { key: '2', label: '项目二', children: '项目二的内容', closable: true },
      ]);
      const addTab = () => {
        const key = String(++sequence.current);
        setItems((list) => [
          ...list,
          { key, label: `项目 ${key}`, children: `项目 ${key} 的内容`, closable: true },
        ]);
      };
      return (
        <Space direction="vertical" align="stretch">
          <Tabs
            aria-label="可关闭标签页"
            items={items}
            type="card"
            onClose={(key) => setItems((list) => list.filter((item) => item.key !== key))}
            onAdd={addTab}
            addLabel="新增标签页"
          />
          {items.length === 0 && (
            <Space>
              <Button variant="outline" onClick={addTab}>
                新增标签页
              </Button>
            </Space>
          )}
        </Space>
      );
    }
    

    扩展用法

    项目 1 内容
    extensions.tsx
    import { Button, Space, type TabItem, Tabs } from '@ifhover/leaf-ui';
    
    import { useRef, useState } from 'react';
    
    export function ExtensionDemo() {
      const count = useRef(7);
      const [items, setItems] = useState<TabItem[]>(
        Array.from({ length: 6 }, (_, i) => ({
          key: String(i),
          label: `项目 ${i + 1}`,
          children: `项目 ${i + 1} 内容`,
          closable: true,
        })),
      );
      const addTab = () => {
        const id = String(count.current++);
        setItems((current) => [
          ...current,
          { key: id, label: `项目 ${id}`, children: '新项目', closable: true },
        ]);
      };
      return (
        <Space direction="vertical" align="stretch">
          <Tabs
            aria-label="可排序标签页"
            items={items}
            sortable
            onReorder={setItems}
            onAdd={addTab}
            onClose={(key) => setItems((current) => current.filter((item) => item.key !== key))}
          />
          {items.length === 0 && (
            <Space>
              <Button variant="outline" onClick={addTab}>
                新增标签页
              </Button>
            </Space>
          )}
        </Space>
      );
    }
    

    底部与右侧

    底部标签页
    Design settings
    右侧标签页
    Design settings
    capabilities.tsx
    import { Space, Tabs } from '@ifhover/leaf-ui';
    
    const items = [
      { key: 'design', label: 'Design', children: 'Design settings' },
      { key: 'tokens', label: 'Tokens', children: 'Theme tokens' },
    ];
    
    export function Capabilities() {
      return (
        <Space direction="vertical" align="stretch">
          <Space direction="vertical" align="stretch" size="sm">
            <span>{'底部标签页'}</span>
            <Tabs
              aria-label={'底部标签页'}
              placement="bottom"
              items={items}
            />
          </Space>
          <Space direction="vertical" align="stretch" size="sm">
            <span>{'右侧标签页'}</span>
            <Tabs aria-label={'右侧标签页'} placement="right" items={items} />
          </Space>
        </Space>
      );
    }
    

    Tabs API

    属性类型默认值说明
    itemsreadonly TabItem[]必填标签页列表;为空时不渲染组件
    activeKeystring首个可用项受控激活项 / 初始项
    defaultActiveKeystring首个可用项受控激活项 / 初始项
    onChange(key: string) => void—激活项变化
    type'line' | 'card''line'标签形态
    placement'top' | 'bottom' | 'left' | 'right''top'标签栏位置
    size'sm' | 'md' | 'lg''md'标签尺寸;卡片样式包含标签栏的内边距和边框
    activationMode'automatic' | 'manual''automatic'方向键直接激活 / 回车或空格激活
    destroyInactivebooleanfalse切走时卸载内容
    extraReactNode—标签栏附加内容
    onClose(key: string, event: MouseEvent<HTMLButtonElement>) => void—请求关闭,由应用移除 items 中的项;可阻止默认切换
    onAdd() => void—添加页签,传入后显示添加按钮
    addLabelstring—添加按钮的可访问名称
    overflowbooleantrue溢出页签收进更多菜单
    sortablebooleanfalse启用排序,配合 onReorder 使用
    onReorder(items: TabItem[]) => void—返回排序后的页签

    TabItem

    属性类型默认值说明
    keystring必填必需。唯一标识
    labelReactNode必填必需。标签名称
    childrenReactNode必填必需。对应内容
    disabledbooleanfalse禁用交互。
    iconReactNode—前置图标
    closablebooleanfalse展示关闭按钮,需配合 onClose

    类型

    定义组件属性或组装列表时可导入相关类型。

    import type { TabsProps, TabItem } from '@ifhover/leaf-ui';

    使用说明

    内容首次访问时挂载,默认保留访问过的内容和输入状态。方向键会跳过禁用项,Home / End 跳至首尾;manual 模式适合内容切换需要等待的场景。