All files / src/components/Textfield TruncatedTextArea.tsx

0% Statements 0/20
0% Branches 0/15
0% Functions 0/5
0% Lines 0/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71                                                                                                                                             
import React, { useEffect, useRef, useState } from 'react';
import { TruncateConfig } from './Textfield';
import { Link, Typography, useTheme } from '@mui/material';
 
interface TruncatedTextAreaProps {
  preserveNewlines?: boolean;
  truncateConfig: TruncateConfig;
  value?: string | number;
}
 
const TruncatedTextArea = ({ preserveNewlines, truncateConfig, value }: TruncatedTextAreaProps) => {
  const { maxHeight, showLessText, showMoreText, showTextStyle, valueTextStyle } = truncateConfig;
 
  const theme = useTheme();
  const [showAll, setShowAll] = useState(false);
  const [needsTruncating, setNeedsTruncating] = useState(false);
  const [totalHeight, setTotalHeight] = useState(0);
  const ref = useRef<HTMLParagraphElement>(null);
 
  useEffect(() => {
    if (ref && ref.current && !totalHeight) {
      const height = ref.current.clientHeight;
      setTotalHeight(height);
      setNeedsTruncating(height > maxHeight);
    }
  }, [maxHeight, ref, totalHeight]);
 
  const toggleShowAll = () => setShowAll((prev) => !prev);
 
  const textStyle: Record<string, any> = {
    ...valueTextStyle,
    margin: '8px 0',
    padding: 0,
    overflow: 'hidden',
    width: '100%',
  };
 
  if (needsTruncating && !showAll) {
    textStyle.maxHeight = `${maxHeight}px`;
  }
 
  return (
    <>
      <p
        ref={ref}
        className={`textfield-value--display${preserveNewlines ? ' preserve-newlines' : ''}`}
        style={textStyle}
      >
        {value}
      </p>
 
      {needsTruncating && (
        <div>
          <Link
            component='button'
            onClick={toggleShowAll}
            onBlur={() => setShowAll(false)}
            sx={{ color: theme.palette.TwClrTxtBrand, textDecorationColor: `${theme.palette.TwClrTxtBrand}80` }}
          >
            <Typography sx={{ ...showTextStyle, marginTop: '-3px' }}>
              {showAll ? showLessText : showMoreText}
            </Typography>
          </Link>
        </div>
      )}
    </>
  );
};
 
export default TruncatedTextArea;