返回文章列表
·2 分钟阅读

InputEllipsis 实现

背景

需要一种在 disabled 情况下会显示 Tooltip 的输入框

实现

// index.tsx

import { Form, Input, InputProps, Tooltip } from "antd";
import styles from "./index.module.less";
import React from "react";
import type { FormItemProps, InputRef } from "antd";

export const InputEllipsis = (props: InputProps) => {
  const { value, disabled, className, ...restProps } = props;
  const [isTooltipCouldVisible, setIsTooltipCouldVisible] =
    React.useState(false);
  const inputRef = React.useRef<InputRef>(null);

  // 检测文本是否溢出
  const checkOverflow = () => {
    const inputElement = inputRef.current;
    if (inputElement) {
      // 获取 input 元素实际的输入框部分
      const { input } = inputElement;
      if (input) {
        // 使用 clientWidth(可视区域宽度)和 scrollWidth(实际内容宽度)比较
        const { clientWidth, scrollWidth } = input;
        setIsTooltipCouldVisible(scrollWidth > clientWidth);
      }
    }
  };

  // 监听输入框内容变化和尺寸变化
  React.useEffect(() => {
    checkOverflow();
  }, [value]);

  React.useEffect(() => {
    window.addEventListener("resize", checkOverflow);
    return () => {
      window.removeEventListener("resize", checkOverflow);
    };
  }, []);

  if (disabled) {
    return (
      <Tooltip
        title={value}
        {...(isTooltipCouldVisible ? {} : { open: false })}
      >
        <span>
          <Input
            ref={inputRef}
            value={value}
            disabled={disabled}
            placeholder={"请输入"}
            {...restProps}
            className={`${styles.customEllipsisInput} ${className || ""}`}
          />
        </span>
      </Tooltip>
    );
  } else {
    return (
      <Input
        value={value}
        disabled={disabled}
        className={className}
        placeholder={"请输入"}
        {...restProps}
      />
    );
  }
};

interface InputEllipsisFormItemProps extends FormItemProps {
  fieldProps?: InputProps;
}

export const InputEllipsisFormItem = (props: InputEllipsisFormItemProps) => {
  const { fieldProps, ...restProps } = props;
  return (
    <Form.Item {...restProps}>
      <InputEllipsis {...fieldProps} />
    </Form.Item>
  );
};
// index.module.less

.customEllipsisInput {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}