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

如何让自定义MUI ToggleButton宽度随文本变化平滑过渡?

实现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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 00:10:13