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> ); }
关键逻辑说明
- 状态管理:用
expandedTabs对象统一存储所有标签的展开状态,避免为每个标签单独声明状态,提升可维护性。 - 事件绑定:
onMouseEnter:鼠标悬停时将对应标签的展开状态设为true,显示名称onMouseLeave:鼠标离开时设为false,收起名称(若需要点击后保持展开,可移除该事件或调整逻辑)onClick:点击标签时切换展开状态,实现点击后固定显示名称的效果(可选)
- 样式优化:给
Tabs.Tab添加transition样式实现平滑宽度变化;图标右侧间距随展开状态动态调整,优化视觉体验。 - 条件渲染:通过布尔状态控制标签名称的显示/隐藏,配合图标完成仅图标、图标+名称的切换。
可选优化
- 如果希望激活的标签始终显示名称,可修改状态更新逻辑:
const toggleTabExpand = (tabValue: string, expand: boolean) => { setExpandedTabs(prev => ({ ...prev, [tabValue]: tabValue === activeTab ? true : expand })); }; - 可使用Mantine的
Box组件或自定义CSS类替代内联样式,统一管理过渡和间距规则。
内容的提问来源于stack exchange,提问作者Biaspoint
相关产品推荐
相关产品推荐

