You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何实现Mantine标签仅显示图标,hover/点击时展开名称?

在React中实现Mantine标签仅显示图标、悬停/点击时展开名称的方案

问题描述

需要在React原生Mantine组件中实现Tabs标签的交互效果:默认仅显示图标,鼠标悬停或点击标签时展开显示完整名称。目前已知非原生的Dash版Mantine组件及Shiny框架有类似实现,但原生Mantine未找到明确方案。尝试通过状态变量控制标签名的显示(初始为空,悬停时设为正常名称),需明确hover逻辑的添加位置。

原基础代码:

import { useState } from 'react';
import { Tabs } from '@mantine/core';

function Demo() {
  const [activeTab, setActiveTab] = useState<string | null>('first');

  return (
    <Tabs value={activeTab} onTabChange={setActiveTab}>
      <Tabs.List>
        <Tabs.Tab value="first">First tab</Tabs.Tab>
        <Tabs.Tab value="second">Second tab</Tabs.Tab>
      </Tabs.List>

      <Tabs.Panel value="first">First panel</Tabs.Panel>
      <Tabs.Panel value="second">Second panel</Tabs.Panel>
    </Tabs>
  );
}

实现方案

核心思路

通过React状态管理每个标签的展开状态,结合Tabs.Tab的鼠标事件(悬停/离开)和点击事件控制状态切换,配合Mantine图标组件实现图标+名称的动态显示,再用CSS过渡实现平滑展开效果。

完整实现代码

import { useState } from 'react';
import { Tabs } from '@mantine/core';
import { HomeIcon, SettingsIcon } from '@mantine/icons'; // 引入所需图标

function Demo() {
  const [activeTab, setActiveTab] = useState<string | null>('first');
  // 用对象管理每个标签的展开状态,默认都不展开
  const [expandedTabs, setExpandedTabs] = useState({
    first: false,
    second: false,
  });

  // 更新标签展开状态的通用函数
  const toggleTabExpand = (tabValue: string, expand: boolean) => {
    setExpandedTabs(prev => ({ ...prev, [tabValue]: expand }));
  };

  return (
    <Tabs value={activeTab} onTabChange={setActiveTab}>
      <Tabs.List>
        <Tabs.Tab
          value="first"
          // 鼠标进入时展开标签名
          onMouseEnter={() => toggleTabExpand('first', true)}
          // 鼠标离开时收起标签名(可选:若需点击后保持展开,可调整逻辑)
          onMouseLeave={() => toggleTabExpand('first', false)}
          // 点击时切换展开状态(可选:实现点击固定显示名称)
          onClick={() => toggleTabExpand('first', !expandedTabs.first)}
          // 添加过渡效果,让宽度变化更平滑
          style={{ transition: 'width 0.2s ease' }}
        >
          <HomeIcon style={{ marginRight: expandedTabs.first ? '8px' : 0 }} />
          {/* 根据状态控制名称显示 */}
          {expandedTabs.first && '首页'}
        </Tabs.Tab>
        
        <Tabs.Tab
          value="second"
          onMouseEnter={() => toggleTabExpand('second', true)}
          onMouseLeave={() => toggleTabExpand('second', false)}
          onClick={() => toggleTabExpand('second', !expandedTabs.second)}
          style={{ transition: 'width 0.2s ease' }}
        >
          <SettingsIcon style={{ marginRight: expandedTabs.second ? '8px' : 0 }} />
          {expandedTabs.second && '设置'}
        </Tabs.Tab>
      </Tabs.List>

      <Tabs.Panel value="first">首页面板内容</Tabs.Panel>
      <Tabs.Panel value="second">设置面板内容</Tabs.Panel>
    </Tabs>
  );
}

关键逻辑说明

  1. 状态管理:用expandedTabs对象统一存储所有标签的展开状态,避免为每个标签单独声明状态,提升可维护性。
  2. 事件绑定:
    • onMouseEnter:鼠标悬停时将对应标签的展开状态设为true,显示名称
    • onMouseLeave:鼠标离开时设为false,收起名称(若需要点击后保持展开,可移除该事件或调整逻辑)
    • onClick:点击标签时切换展开状态,实现点击后固定显示名称的效果(可选)
  3. 样式优化:给Tabs.Tab添加transition样式实现平滑宽度变化;图标右侧间距随展开状态动态调整,优化视觉体验。
  4. 条件渲染:通过布尔状态控制标签名称的显示/隐藏,配合图标完成仅图标、图标+名称的切换。

可选优化

  • 如果希望激活的标签始终显示名称,可修改状态更新逻辑:
    const toggleTabExpand = (tabValue: string, expand: boolean) => {
      setExpandedTabs(prev => ({
        ...prev,
        [tabValue]: tabValue === activeTab ? true : expand
      }));
    };
    
  • 可使用Mantine的Box组件或自定义CSS类替代内联样式,统一管理过渡和间距规则。

内容的提问来源于stack exchange,提问作者Biaspoint

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:52:53