"use client" import * as React from "react" import { cn } from "../../lib/utils" /** * `Truncate` is the replacement for `@wordpress/components`' `__experimentalTruncate` - * **3 imports across 3 files**. * * AN ADAPTER, NOT A RENAME, AND THE REASON IS EASY TO MISS. WordPress only clamps when the children * are a **string or a number**. Anything else passes straight through with no clamp at all - and one * of the three call sites, `fhirHumanName`'s stacked names, passes elements. Clamping those would be * a new visual, not a port, so the same test is applied here. * * `numberOfLines` is the only prop any call site passes, and all three pass `1`. * 0 (WP default) one line, ellipsis at the end * n clamped to n lines * WordPress adds `word-break: break-all` at exactly one line so an unbreakable URL still clamps * instead of blowing the row out. That is reproduced. * * WP's `limit` and `ellipsizeMode` cut the text itself rather than the box. No call site uses them, * so they are not accepted. */ export interface TruncateProps extends React.ComponentProps<"span"> { numberOfLines?: number } // Spelled out rather than built from a template, because Tailwind reads class names as literal text: // `line-clamp-${n}` compiles to nothing. Beyond six the clamp is dropped, which is what WP's own // -webkit-line-clamp does on browsers that cannot honour the count. const LINE_CLAMP: Record = { 1: "line-clamp-1 break-all", 2: "line-clamp-2", 3: "line-clamp-3", 4: "line-clamp-4", 5: "line-clamp-5", 6: "line-clamp-6", } function Truncate({ numberOfLines = 0, className, children, ...props }: TruncateProps) { const shouldTruncate = typeof children === "string" || typeof children === "number" const clamp = numberOfLines > 0 ? LINE_CLAMP[numberOfLines] : "block truncate" return ( {children} ) } export { Truncate }