web-dev-qa-db-fra.com

React Afficher la totalité de matériau-UI uniquement pour le texte qui a des ellipsis

À la recherche d'un moyen d'avoir une info-bulle de matériau-ui élargir le texte dans une cellule de table [~ # ~] uniquement [~ # ~] Si le texte est coupé avec une ellipsie (débordant).

Actuellement dans ma table, j'ai une cellule comme ceci:

<TableCell className={classes.descriptionCell}>{row.description}</TableCell>

et mon style pour la descriptionCell est comme ceci:

    descriptionCell: {
        whiteSpace: 'nowrap',
        maxWidth: '200px',
        overflow: 'hidden',
        textOverflow: 'Ellipsis'
    }

Cela rend le texte se comporter comme je l'aimerais dans cette table, mais je veux pouvoir survoler et voir le reste d'entre eux dans une info-bulle, de préférence le composant d'info-bulle intégré de matériau-ui.

Je sais qu'il existe un paquet qui existe ici https://www.npmjs.com/package/react-ellipipsis-with-tooltip qui devrait faire cela, mais il utilise bootstrap info-bulle, non matériau UI.

7
dave99collins

J'ai couru dans ce même problème aujourd'hui et la réponse de Vijay-Menon était très utile. Voici un composant autonome simple pour la même chose:

import React, { Component } from 'react';
import Tooltip from '@material-ui/core/Tooltip';

class OverflowTip extends Component {
    constructor(props) {
        super(props);
        this.state = {
            overflowed: false
        };
        this.textElement = React.createRef();
    }

    componentDidMount () {
        this.setState({
            isOverflowed: this.textElement.current.scrollWidth > this.textElement.current.clientWidth
        });
    }

    render () {
        const { isOverflowed } = this.state;
        return (
            <Tooltip
                title={this.props.children}
                disableHoverListener={!isOverflowed}>
                <div
                    ref={this.textElement}
                    style={{
                        whiteSpace: 'nowrap',
                        overflow: 'hidden',
                        textOverflow: 'Ellipsis'
                    }}>
                    {this.props.children}
                </div>
            </Tooltip>
        );
    }
}

Exemple d'utilisation:

<OverflowTip>
      some long text here that may get truncated based on space
</OverflowTip>

La nuisance est que si l'espace de l'élément change de manière dynamique dans la page (E.g. redimensionnez ou dynamique changez de DOM), il ne reconnaîtra pas le nouvel espace et de recalculer s'il est débordé.

D'autres bibliothèques d'info-bulle comme Tippy ont une méthode qui est tirée lorsque essayer pour ouvrir l'info-bulle. C'est un endroit parfait pour faire le chèque de trop-plein car cela fonctionnera toujours, peu importe si la largeur DOM avait changé pour l'élément de texte. Malheureusement, il est plus difficile de faire cela avec l'API fournie par UI du matériel.

3
benjamin.keen

basé sur @Dheeraj Réponse - c'est le très proche de son composant mais dans la version de script de type et plus fait des noms d'accessoires de sens:

import React, { useRef, useEffect, useState } from 'react';
import Tooltip from '@material-ui/core/Tooltip';

interface Props {
  tooltip: string;
  text: string;
}

const OverflowTooltip = (props: Props) => {

  const textElementRef = useRef<HTMLInputElement | null>(null);

  const compareSize = () => {
    const compare =
      textElementRef.current.scrollWidth > textElementRef.current.clientWidth;
    setHover(compare);
  };

  useEffect(() => {
    compareSize();
    window.addEventListener('resize', compareSize);
  }, []);

  useEffect(() => () => {
    window.removeEventListener('resize', compareSize);
  }, []);

  const [hoverStatus, setHover] = useState(false);

  return (
    <Tooltip
      title={props.tooltip}
      interactive
      disableHoverListener={!hoverStatus}
    >
      <div
        ref={textElementRef}
        style={{
          whiteSpace: 'nowrap',
          overflow: 'hidden',
          textOverflow: 'Ellipsis',
        }}
      >
        {props.text}
      </div>
    </Tooltip>
  );
};

export default OverflowTooltip;

et nous l'utilisons comme ceci:

<OverflowTooltip 
    tooltip={'tooltip message here'}
    text={'very long text here'}
/>
2
Erez Lieberman

basé sur Benjamin.keen Réponse, il s'agit de la version fonctionnelle de son code:

import React, { useRef, useState, useEffect } from 'react';
import Tooltip from '@material-ui/core/Tooltip';

const OverflowTip = ({ children }) => {
  const [isOverflowed, setIsOverflow] = useState(false);
  const textElementRef = useRef();
  useEffect(() => {
    setIsOverflow(textElementRef.current.scrollWidth > textElementRef.current.clientWidth);
  }, []);
  return (
    <Tooltip title={children} disableHoverListener={!isOverflowed}>
      <div
        ref={textElementRef}
        style={{
          whiteSpace: 'nowrap',
          overflow: 'hidden',
          textOverflow: 'Ellipsis',
        }}
      >
        {children}
      </div>
    </Tooltip>
  );
};
1
iradkot