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
)
}