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 | 1x 1x 1x 1x 1x 1x 1x 6x 6x 6x 6x 6x 1x 1x 6x 2x 2x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x | import { display } from '@/../config.json';
import { DescriptionToggleLink } from '@/components/StyledComponents';
import { i18n } from '@/helpers/i18n';
import { type KeyboardEvent, type ReactElement, useState } from 'react';
interface TruncatedDescriptionProps {
/** The full description text to render. */
text: Maybe<string>;
/** Character limit before truncation; defaults to `display.descriptionPreviewLength` in config.json. */
limit?: number;
}
/**
* Renders a product description, truncating it to `limit` characters 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.
* @param props - The description text and optional character limit.
* @returns The (optionally truncated) description with a toggle, or null when empty.
* @example
* ```tsx
* <TruncatedDescription text={product.description} />
* <TruncatedDescription text={longText} limit={120} />
* ```
* @source
*/
export function TruncatedDescription({
text,
limit = display.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>
);
}
|