The description text and optional character limit.
The (optionally truncated) description with a toggle, or null when empty.
<TruncatedDescription text={product.description} />
<TruncatedDescription text={longText} limit={120} />
export function TruncatedDescription({
text,
limit = descriptionPreviewLength,
}: TruncatedDescriptionProps): ReactElement | null {
const [expanded, setExpanded] = useState(false);
if (!text) {
return null;
}
if (text.length <= limit) {
return <span className="detail-value">{text}</span>;
}
const preview = expanded ? text : `${text.slice(0, limit).trimEnd()}…`;
const toggle = () => setExpanded((prev) => !prev);
return (
<span className="detail-value">
{preview}
<DescriptionToggleLink
role="button"
tabIndex={0}
onClick={toggle}
onKeyDown={(event: KeyboardEvent<HTMLSpanElement>) => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
toggle();
}
}}
>
[{expanded ? i18n('common_show_less') : i18n('common_show_more')}]
</DescriptionToggleLink>
</span>
);
}
Renders a product description, truncating it to
limitcharacters with an inline "[more]" toggle when it is longer. Expanding reveals the full text with a "[less]" toggle to collapse it back to the preview length. Short descriptions (and empty ones) render without a toggle.