如何让自定义MUI ToggleButton宽度随文本变化平滑过渡?
核心思路
按钮宽度突兀变化是因为文本切换时无过渡动画,宽度随内容即时变更。通过给按钮添加宽度过渡动画并固定文本排版规则,就能实现平滑的宽度变化效果。
修改方案
在buildSX函数中新增过渡及排版样式,确保按钮宽度变化时触发动画,同时避免文本换行干扰宽度计算:
const buildSX = (theme: Theme) => ({ // 保留原有样式,新增以下内容 transition: 'width 0.3s ease-in-out', // 给宽度变化添加平滑过渡动画 whiteSpace: 'nowrap', // 强制文本单行显示,避免换行导致宽度异常波动 width: 'fit-content', // 让按钮宽度自适应当前文本长度 minWidth: theme.spacing(8), // 可选:设置最小宽度,防止文本过短时按钮过窄(可根据需求调整值) });
同时给内部Typography添加单行规则,确保文本不会换行:
<Typography data-selenium={typographyDataSelenium} sx={{ whiteSpace: 'nowrap' }} > {children} </Typography>
完整修改后的组件代码
import { type Theme, ToggleButton as MUIToggleButton, ToggleButtonProps, useTheme, } from '@mui/material'; import { IWithSeleniumAttribute } from '../../../../interfaces'; import { Typography } from '../../../index'; export interface ITabProps extends ToggleButtonProps, IWithSeleniumAttribute { typographyDataSelenium?: string; } const buildSX = (theme: Theme) => ({ // 原有样式保留 transition: 'width 0.3s ease-in-out', whiteSpace: 'nowrap', width: 'fit-content', minWidth: theme.spacing(8), // 可根据设计需求调整或移除 }); const Tab = (props: ITabProps) => { const { typographyDataSelenium, children, sx = [], ...restProps } = props; const theme = useTheme(); return ( <MUIToggleButton sx={[ buildSX(theme), ...(Array.isArray(sx) ? sx : [sx]), ]} {...restProps} > <Typography data-selenium={typographyDataSelenium} sx={{ whiteSpace: 'nowrap' }} > {children} </Typography> </MUIToggleButton> ); }; export default Tab;
额外说明
- 过渡时长
0.3s可按需调整(比如0.2s更快,0.4s更平缓)。 - 如果文本长度差异极大,担心按钮宽度变化范围过大,可结合
maxWidth和textOverflow: 'ellipsis'限制最大宽度,但这会截断过长文本,需根据设计需求权衡。
内容的提问来源于stack exchange,提问作者r_metal
相关产品推荐
相关产品推荐

