Search code examples
performancematerial-uitooltiprating

MUI Rating Custom Tooltip to increase the rendering performance


I am trying to show tooltips when the user selects a rating star with the following code, but the performance is very poor (it is a part of huge MUI components).

I am wondering if I can achieve the same effect with IconContainerComponent. Is that possible?

<Tooltip title={labels[ratingTooltipValue !== -1 ? ratingTooltipValue : 1]}>
<Box display="inline-block">
<Rating
   value={parseInt(field.value, 10)}
   onChange={(newValue) => {
      field.onChange(newValue);
   }}
   precision={1}
   size="small"                                       
   readOnly={viewMode}
   onChangeActive={(event, newHover) => {
      setRatingTooltipValue(newHover);
   }}

/>
</Box>
</Tooltip>

Performance example

https://codesandbox.io/p/sandbox/priceless-feather-w3rrpf?file=%2Fdemo.tsx%3A12%2C18

EDIT I added a 2-second delay inside the onChangeActive and now it seems much better. As an alternative solution, can I use a custom tooltip inside the IconContainerComponent


Solution

  • enter image description here

    Here is the answer

    const TOOLTIP_LABELS = {
       1: 'Useless',
       2: 'Poor',
       3: 'Good',
       4: 'Very Good',
       5: 'Excellent',
    };
    .....
    
    <Rating
       value={rating}
       onChange={(newValue) => {
          setNewRating(newValue);
       }}
       precision={1}
       size="small"                                              
       onChangeActive={(event, newHover) => {
        const tooltip = document.getElementById(`label-onrate`);
        if (newHover !== -1) {
           tooltip.innerHTML = TOOLTIP_LABELS[newHover];
           tooltip.style.visibility = 'visible';
        } else {
           tooltip.style.visibility = 'hidden';
        }
     }}
    />
    <div className="tooltip">
       <span className="tooltiptext" id={`label-onrate`} />
    </div>
    

    and the CSS file

    .tooltip {
      position: relative;
      display: inline-block;  
    }
    
    /* Tooltip text */
    .tooltip .tooltiptext {
      width: 120px;
      top: -60px;
      left: 50%;  
      margin-left: -100px;  
    
      display: inline-block;
      visibility: hidden;  
      background-color: white;
      color: #000;
      text-align: center;
      padding: 5px 0;
      border-radius: 6px;
     
      
      position: absolute;
      z-index: 1300;
    }
    
    /* arrow */
    .tooltip .tooltiptext::after {
      content: " ";
      position: absolute;
      top: 100%; 
      left: 50%;
      margin-left: -5px;
      border-width: 5px;
      border-style: solid;
      border-color: white transparent transparent transparent;
    }