import React from 'react' import Tooltip from '../components/Tooltip/Tooltip' const SHORT_WORD_LENGTH = 3 const SINGLE_WORD_THRESHOLD = 20 const SINGLE_WORD_TRUNCATION = 18 const MAX_LINE_LENGTH = 20 /** * Creates a one or two-line label for table headers with smart truncation and tooltips. * The maximum total length of a displayed header is 36 characters, with each line limited to 20 characters. * If text exceeds these limits: * - For single words: truncates at 18 characters with "..." and shows full text in tooltip * - For multiple words: splits into two lines of max 20 characters each * - If second line exceeds limit: truncates with "..." and shows full text in tooltip * * @param label - The text content of the label * @param twoLineLabel - Whether to split the label into two lines * @returns React component with formatted label */ export const createTwoLineLabel = (label: string, twoLineLabel?: boolean) => { if (!twoLineLabel) { return <>{label} } let isTruncated = false const words = label.split(' ') // Handle single long word case first if (words.length === 1 && label.length > SINGLE_WORD_THRESHOLD) { const shortenedLabel = label.substring(0, SINGLE_WORD_TRUNCATION) + '...' isTruncated = true return (
{shortenedLabel}
) } // Return single line for: single words, empty strings, or two very short words if ( words.length === 1 || label.trim() === '' || (words.length === 2 && (words[0].length <= SHORT_WORD_LENGTH || words[1].length <= SHORT_WORD_LENGTH)) ) { return
{label}
} // Try all possible word combinations to find optimal split let bestSplit = { firstLine: '', secondLine: '', maxLength: Infinity } for (let i = 1; i < words.length; i++) { const firstLine = words.slice(0, i).join(' ') const secondLine = words.slice(i).join(' ') // Skip if either line exceeds max length if ( firstLine.length > MAX_LINE_LENGTH || secondLine.length > MAX_LINE_LENGTH ) { continue } // Calculate the maximum line length of this combination const maxLineLength = Math.max(firstLine.length, secondLine.length) // Update best split if this combination has a shorter maximum line length if (maxLineLength < bestSplit.maxLength) { bestSplit = { firstLine, secondLine, maxLength: maxLineLength, } } } // If no valid split was found within MAX_LINE_LENGTH if (bestSplit.maxLength === Infinity) { // Find the maximum number of complete words that fit in the first line let i = 0 let firstLine = '' while (i < words.length) { const nextLine = words.slice(0, i + 1).join(' ') if (nextLine.length > MAX_LINE_LENGTH) break firstLine = nextLine i++ } const secondLine = words.slice(i).join(' ') bestSplit.firstLine = firstLine bestSplit.secondLine = secondLine.length > MAX_LINE_LENGTH ? secondLine.substring(0, MAX_LINE_LENGTH - 3) + '...' : secondLine isTruncated = secondLine.length > MAX_LINE_LENGTH } const labelContent = (
{bestSplit.firstLine}
{bestSplit.secondLine}
) return isTruncated ? ( {labelContent} ) : ( labelContent ) }