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

MUI Autocomplete输入框选中元素超宽时能否添加悬浮提示?

MUI Autocomplete 选中内容超出容器时添加悬浮Tooltip的优化实现

当然可以只针对选中值做Tooltip包裹,完全不需要把整个TextField套进去,这样就能避免不必要的重绘问题。核心思路是仅在选中内容宽度超出容器时,才对该内容渲染Tooltip,具体分两种场景实现:

1. 单个选中值的场景

利用renderInput自定义输入框内部的内容渲染,通过动态计算文本宽度判断是否需要显示Tooltip:

import { Autocomplete, TextField, Tooltip } from '@mui/material';
import { useRef, useState, useEffect } from 'react';

const options = [
  { label: '非常长的选项名称示例1234567890abcdefghijklmnopqrstuvwxyz', value: 1 },
  { label: '短选项', value: 2 },
];

export default function SingleAutocompleteWithTooltip() {
  const [selectedValue, setSelectedValue] = useState(null);
  const inputContainerRef = useRef(null);
  const textRef = useRef(null);
  const [showTooltip, setShowTooltip] = useState(false);

  // 监听选中值变化,计算宽度
  useEffect(() => {
    if (!inputContainerRef.current || !textRef.current) return;
    // 减去输入框内边距、图标的宽度(可根据实际布局调整数值)
    const availableWidth = inputContainerRef.current.offsetWidth - 60;
    const textWidth = textRef.current.offsetWidth;
    setShowTooltip(textWidth > availableWidth);
  }, [selectedValue]);

  return (
    <Autocomplete
      options={options}
      value={selectedValue}
      onChange={(e, newValue) => setSelectedValue(newValue)}
      renderInput={(params) => (
        <TextField
          {...params}
          inputRef={inputContainerRef}
          InputProps={{
            ...params.InputProps,
            // 自定义输入框内容,包裹选中文本用于宽度计算
            inputComponent: ({ ...rest }) => {
              const inputContent = selectedValue?.label || params.inputProps.placeholder;
              return showTooltip ? (
                <Tooltip title={inputContent}>
                  <span ref={textRef}>{inputContent}</span>
                </Tooltip>
              ) : (
                <span ref={textRef}>{inputContent}</span>
              );
            },
          }}
        />
      )}
    />
  );
}

2. 多选标签场景

通过renderTags属性自定义每个选中标签的渲染,单独判断每个标签是否被截断(scrollWidth > offsetWidth),仅对截断的标签添加Tooltip:

import { Autocomplete, TextField, Chip, Tooltip } from '@mui/material';
import { useRef, useState, useEffect } from 'react';

const options = [
  { label: '超长选项名称1234567890abcdefghijklmnopqrstuvwxyz', value: 1 },
  { label: '普通长度选项', value: 2 },
  { label: '短选项', value: 3 },
];

export default function MultiAutocompleteWithTooltip() {
  const [selectedValues, setSelectedValues] = useState([]);
  const chipRefs = useRef([]);
  const [showTooltipForChip, setShowTooltipForChip] = useState({});

  // 每次选中值变化时,检查所有标签是否截断
  useEffect(() => {
    const newTooltipStates = {};
    chipRefs.current.forEach((ref, index) => {
      if (ref) {
        newTooltipStates[index] = ref.scrollWidth > ref.offsetWidth;
      }
    });
    setShowTooltipForChip(newTooltipStates);
  }, [selectedValues]);

  return (
    <Autocomplete
      multiple
      options={options}
      value={selectedValues}
      onChange={(e, newValue) => setSelectedValues(newValue)}
      renderTags={(value, getTagProps) =>
        value.map((option, index) => {
          const tagProps = getTagProps({ index });
          return (
            <div key={index} ref={el => chipRefs.current[index] = el}>
              {showTooltipForChip[index] ? (
                <Tooltip title={option.label}>
                  <Chip {...tagProps} label={option.label} />
                </Tooltip>
              ) : (
                <Chip {...tagProps} label={option.label} />
              )}
            </div>
          );
        })
      }
      renderInput={(params) => <TextField {...params} label="多选选项" />}
    />
  );
}

关键优化点

  • 仅在选中内容确实超出容器时才渲染Tooltip,避免了全局包裹带来的无意义重绘
  • 宽度计算逻辑可根据你的实际布局(比如内边距、图标尺寸)调整,确保判断准确
  • 多选场景下精准控制单个标签的Tooltip显示,交互更友好

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:02:33